自定义的Base64编码器无法正确进行编码

3
我决定自己制作Base64编码器和解码器,尽管标准库中已经有了这个模块。这只是一个有趣的项目。然而,编码器出现了一些问题,错误地编码了一些字符,我没有成功进行调试。我尝试严格按照维基百科上找到的模型进行操作。我认为问题与底层的二进制格式转换有关,但我不确定。 代码:
def encode_base64(data):
    raw_bits = ''.join('0' + bin(i)[2:] for i in data)
    # First bit is usually (always??) 0 in ascii characters
    
    split_by_six = [raw_bits[i: i + 6] for i in range(0, len(raw_bits), 6)]
    
    if len(split_by_six[-1]) < 6: # Add extra zeroes if necessary
        split_by_six[-1] = split_by_six[-1] + ((6 - len(split_by_six[-1])) * '0')
    
    padding = 2 if len(split_by_six) % 2 == 0 else 1
    if len(split_by_six) % 4 == 0: # See if padding is necessary
        padding = 0
    
    indexer = ([chr(i) for i in range(65, 91)] # Base64 Table
         + [chr(i) for i in range(97, 123)]
         + [chr(i) for i in range(48, 58)]
         + ['+', '/'])
    
    return ''.join(indexer[int(i, base=2)] for i in split_by_six) + ('=' * padding)

当我运行以下示例代码时,我得到了错误的值,如下所示:
print(base_64(b'any carnal pleasure'))
# OUTPUT: YW55QMbC5NzC2IHBsZWFzdXJl=
# What I should be outputting: YW55IGNhcm5hbCBwbGVhc3VyZS4=

出于某种奇怪的原因,前几个字符是正确的,但其余部分不正确。我很乐意回答任何问题!

1个回答

2

Python的bin()函数不包含前导零,因此二进制表示的长度会有所变化:

>>> bin(1)
'0b1'
>>> bin(255)
'0b11111111'
>>> bin(ord("a"))
'0b1100001'
>>> bin(ord(" "))
'0b100000'

在你的输入中,any的二进制表示中都有一个前导零,因此bin(i)的长度是一致的。但是' '的二进制表示有两个前导零,所以bin(i)比您期望的少一位,其余的raw_bits也会错位。

要解决这个问题,确保在二进制表示中填充前导零,直到它为8个字符。我认为没有特别优雅的方法来做到这一点,但是您可以使用format(ord(i), "#010b")[2:]来确保完整的表示为10个字符,然后舍弃0b,留下您关心的8个字符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接