python - 从十六进制转换为 base64

标签 python python-3.x cryptography base64

我的任务是获取十六进制文本并将其转换为 base64 系统。我的问题是我的代码输出不正确。

给定的输入:

49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d

预期输出:

SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t

我程序的输出:

kk7aga2lY2NL5nIHLe6uiBicMLS3IGxp1spAhIHBe0ub9ub3rmQNXVzaOTe3

我希望我的代码如何工作:

注意: 我知道 Python 内置了将某些内容转换为 base64 的方法,以及使用 int() 将任何基数转换为十进制,我选择使用我自己的方法作为一种更好地理解问题的方式。

  1. 获取一串十六进制文本并将其转换为十进制数。
  2. 将十进制数转换为二进制数。
  3. 将二进制数分成 24 位的 block 。
  4. 将 24 位 block 分成 4 个部分,每个部分 6 位。
  5. 将每 6 位转换为十进制数。
  6. 将十进制数转换为 base64 编码的字母/数字。从“A”(索引为 0)到“/”(索引为 63)开始

我的代码:

def convertToDecimal(text, original_base):
    '''
    Program assumes user is using it correctly. It does not bother checking for weird cases like a base being 0 or a negative.
    '''

    decimal = 0  # used for converting to decimal base first
    exp = len(text) - 1  # starting exponent of the base (8^1, 8^0, etc)

    hex_nums = {"a": 10, "b": 11, "c": 12, "d": 13, "e": 14, "f": 15}

    # convert original_base to a decimal number
    for val in text:
        if val in hex_nums:  # have to worry about letters
            val = hex_nums[val]
        decimal += int(val) * (original_base ** exp)
        exp -= 1

    return decimal


def base64(text, base):
    letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

    bin_num = bin(convertToDecimal(text, base))[2:]

    base64_val = ""

    # used for indexing each chunk of binary values
    i = 0
    j = 25

    # used for each chunk of six bits to be converted into a number
    six_bit_chunk = ""

    while True:
        if j > len(bin_num):
            # prevents index out of bounds error
            break

        bin_chunk = bin_num[i:j]  # take a chunk of 24 bits
        for x in range(0, 24, 6):
            six_bit_chunk += bin_chunk[x:x + 6]  # take a smaller chunk of 6 bits
            index = convertToDecimal(six_bit_chunk, 2)  # use the 6 bits to create a decimal value from 0-63
            base64_val += letters[index]
            six_bit_chunk = ""

        i += 25
        j += 25

    return base64_val


new_text = base64("49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d",
                  16)

print(new_text)

我解决这个问题的尝试是查看六位 block 产生的结果,他们正在 base64 中创建正确的十进制数和正确的字母/数字。

最佳答案

你不能直接以 6 为一组迭代二进制表示,而不是按 24 分组并再次分成 4 组吗?

但在分成 6 组之前,它仍然必须用零填充到 24 的倍数。

我的功能:

def base64_v2(text, base):
    base64_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    n1 = 24
    n2 = 6

    dec_num = int(text, base)
    bin_str = bin(dec_num)[2:]

    # pad with zeros to the left to get multiple of 'n1'
    remainder = divmod(len(bin_str), n1)[1]
    if remainder > 0:
        additional_zeros = n1 - remainder
        bin_str = ('0' * additional_zeros) + bin_str

    return ''.join(
        base64_letters[int(bin_str[i:i+n2], 2)]
        for i in range(0, len(bin_str), n2))

我的函数通过了以下所有测试用例:

sample_data = [
    (
        '49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d',
        'SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t',
    ),
    (
        '24e1f218372064987d5457b639819715bddb51558cc4acb3ce6eeacd7afa2751bac0a5c7c3c636f24babff4ad68473db',
        'JOHyGDcgZJh9VFe2OYGXFb3bUVWMxKyzzm7qzXr6J1G6wKXHw8Y28kur/0rWhHPb',
    ),
    (
        '79d6e3a9d5bfba9902274e1b1c2d956fa92d16ba9a972825eb0b32aecd2401653624f900fe79b4550c24aae136ae7260',
        'edbjqdW/upkCJ04bHC2Vb6ktFrqalygl6wsyrs0kAWU2JPkA/nm0VQwkquE2rnJg',
    ),
    (
        'd251b89c473d6336dfeb3714d92c6b2080c863624ca2746e1380bd0642893ba64ebdae23bb7ad9a1f3ad9efbdc2f18e6',
        '0lG4nEc9Yzbf6zcU2SxrIIDIY2JMonRuE4C9BkKJO6ZOva4ju3rZofOtnvvcLxjm',
    ),
    (
        '5c2b578064178ad329f37041b063ec05c3ce8f202bb44e9a1260c6ded11ddd91d25ac83bba31bac7987e2da3a188c23d',
        'XCtXgGQXitMp83BBsGPsBcPOjyArtE6aEmDG3tEd3ZHSWsg7ujG6x5h+LaOhiMI9',
    ),
    (
        '018b79f5c3c1a4f59d12cda25c5ca2a29c4c1fdd1cfdf3f0a4faf350fe384d21bcfd83a8350b49231cf8536595f2a43a',
        'AYt59cPBpPWdEs2iXFyiopxMH90c/fPwpPrzUP44TSG8/YOoNQtJIxz4U2WV8qQ6',
    ),
    (
        'a617cfbe469cecd19f5ac75303a3049319ffb03d9a757c690d7c09d94dbabd6dce2314e1f409e6285fc0a0220eb803fe',
        'phfPvkac7NGfWsdTA6MEkxn/sD2adXxpDXwJ2U26vW3OIxTh9AnmKF/AoCIOuAP+',
    ),
    (
        '2bc40041dbe6937e1113b191fd136bcdd741169e9e81809e83ad3104d447d700ed9d1ab5cfbc113c0731b855fde98f87',
        'K8QAQdvmk34RE7GR/RNrzddBFp6egYCeg60xBNRH1wDtnRq1z7wRPAcxuFX96Y+H',
    ),
    (
        '1904435f5964861c5284b08e0ebf3d201da3ec795a3d9b0f7d5056c4369daed59d42cac72c897356a46305f7aac5fcb4',
        'GQRDX1lkhhxShLCODr89IB2j7HlaPZsPfVBWxDadrtWdQsrHLIlzVqRjBfeqxfy0',
    ),
]

for i, (input_str, expected_output) in enumerate(sample_data):
    print('i              ', i)
    print('input_str      ', input_str)
    print('expected_output', expected_output)

    function_output = base64_v2(input_str, 16)
    print('function_output', function_output)
    assert expected_output == function_output

关于python - 从十六进制转换为 base64,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56876808/

相关文章:

python - 随机 DNA 突变发生器

random - 使用 GMP 进行加密 : how to get random numbers?

python - 在 Dash Python 中下载具有列格式的 Excel 文件

python - 如何使用 pandas datetime 将数字转换为日期(通过使用这些数字作为距今天日期的距离)

python - list.append 或 list +=?

python - 是否有一个更短的版本可以从字典中查找键?

python - Python : HMAC Library vs Hashlib Produces Different Results 中的 HMAC SHA256

node.js - 一次成功加密和解密后,Nodejs Crypto 解密失败

Python 复数零虚部格式化

python - Pycharm 看不到相对路径中带有 ../的文件