自定义Base64编码器无法正确编码

问题描述

尽管标准库中已经有一个用于此的模块,但我还是决定制作自己的Base64编码器和解码器。这只是一个有趣的项目。但是,由于某种原因,编码器会错误地对某些字符进行编码,因此我在调试方面没有运气。我尝试将找到的on Wikipedia模型应用于发球区域。我认为问题与转换为二进制格式的基础有关,但我不确定。

代码

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=

出于某种奇怪的原因,前几个字符是正确的,而其余的则不是。我很高兴回答任何问题!

解决方法

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个字符。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...