繁体   English   中英

从十六进制转换为base64

[英]Converting from hex to base64

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

给出的输入:

49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d

预期产量:

SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t

我的计划输出:

kk7aga2lY2NL5nIHLe6uiBicMLS3IGxp1spAhIHBe0ub9ub3rmQNXVzaOTe3

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

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

  1. 获取一串十六进制文本并将其转换为十进制数。
  2. 将十进制数转换为二进制数。
  3. 将二进制数分成24位的块。
  4. 将24位的块分成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)

我试图解决这个问题的方法是查看六位的块产生了什么,并且它们在base64中创建了正确的十进制数和正确的字母/数字。

我不完全确定这是否正确,但是我做了一些改变,函数的输出与你提供的预期输出相匹配。

更改(还考虑了用户@JamesKPolt的评论):

  • 到处都有你25岁而不是24岁
  • bin_num的开头添加零填充以将长度完成为24的倍数

修改后的代码:

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

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

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

    base64_val = ""

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

    # 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 += 24
        j += 24

    return base64_val

此修改函数通过以下所有测试用例:

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(input_str, 16)
    print('function_output', function_output)
    assert expected_output == function_output

难道你不能直接迭代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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM