我受命接受一个十六进制文本并将其转换为base64系统。我的问题是我的代码输出不正确。
给出的输入:
49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d
预期输出:
SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t
我的程序的输出:
kk7aga2lY2NL5nIHLe6uiBicMLS3IGxp1spAhIHBe0ub9ub3rmQNXVzaOTe3
我希望我的代码如何工作:
注意: 我了解Python建立了将某些东西转换为base64的方法,以及使用int()将任何基数转换为十进制的方法,我选择使用自己的方法作为更多了解问题的方式。
我的代码:
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中创建正确的十进制数字和正确的字母/数字。
答案 0 :(得分:1)
我不确定这是否正确,但是通过一些更改,我实现了该函数的输出与您提供的预期输出相匹配。
更改(还考虑了@JamesKPolt用户的评论):
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
答案 1 :(得分:0)
难道您不能直接遍历以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