我试图将一个字符串解码为base64,然后将其解压缩为zlib,但出现了以下消息:
binascii.Error:无效的base64编码字符串:数据字符数(1957)不能大于4的倍数1
代码:
def decode_token(token):
# token is a string
token_decode = base64.b64decode(token.encode())
token_string = zlib.decompress(token_decode)
return token_string
5条答案
按热度按时间pw9qyyiw1#
1.尝试使用正确数量(1、2或3)的
=
字符填充输入,以使其最终长度为4的倍数。如果令牌长度已经是4的倍数(len(padded_token)%4 == 0
),请跳过该步骤。1.如果你的输入使用的是字符
-_
,你可能会得到同样的错误,在这种情况下,这意味着它是urlsafe编码。在这种情况下,使用base64.urlsafe_b64decode
而不是base64.b64decode
来解码它。uidvcgyl2#
这个错误基本上意味着base64输入不正确。base64编码将每3个输入字节转换为4个ASCII字符,这些字符来自一个有限的集合,但是您传入的数据似乎被解码为不是3字节的偶数倍的内容--就好像有2/3字节滑了进来,并且没有办法解码。非常简单,您的输入已损坏。(您可以尝试从base64中删除一个字符,看看您是否成功解码,但您如何知道解码的数据是正确的,还是只是乱码?)
tquggr8v3#
我也因为修改会话cookie而收到这个错误,当我通过chrome访问django服务器(localhost:8000)时,我收到这个错误,但使用隐姓埋名模式,它工作了。
解决办法是清除我的饼干。我希望这能帮助到别人!
z4iuyo4d4#
我正在用json发送base64音频文件。
在服务器上收到此数据:
base64本身在以下时间之后启动:
您可能还有其他数据。
nwlls2ji5#
什么是Base64?
Base64 encoding使用一个字节的输入数据来表示最多6位的输出。它“浪费空间”是为了确保每个字节都对应于一个普通的、可打印的ASCII符号,使用非常有限的标点符号。其思想是这样就很难意外损坏数据(例如,通过将原始二进制数据馈送到将每个字节的高位用于特殊目的的通信协议),并且易于将数据嵌入到其他上下文中(例如,将二进制数据存储在JSON文档中,而不用担心任何内容被解释为JSON标记的一部分--尽管这是偶然的,因为Base64比JSON早得多)。
为什么对输入长度有限制?
每一个base64输入都代表一个整数字节的输出,每一组4字节的输入巧妙地编码了24位,即3字节的输出数据。
如果在从输入中取出4个字节的组之后,剩下3个,则这些可以表示多达18位; 16位将被用于生成两个数据字节,最后两个被忽略。类似地,如果剩下2位,则可能的12位中的8位将被用于生成一个字节的输出。当然,如果没有剩下任何数据,则没有问题。
然而,如果只剩下一个输入字节,那么它就不能代表足够的数据来产生一个输出字节,整个输入都被浪费了,规范不允许这样做,所以Python会引发一个错误。
为什么数据的长度如此之长?
显然,如果
token_decode = base64.b64decode(token.encode())
从base64.b64decode
部分引发了与数据长度有关的错误,则token.encode
一定产生了无效长度的数据。假设
token
是表示有效Base64数据的字符串,则每个文本字符最终应被转换为单个字节,因此token.encode()
的字节长度将与token
的字符长度匹配;如果token
是有效的Base64数据,那么它必须具有正确的长度,因此,必须违反这些假设之一。也就是说,字符串不可能是有效的Base64数据。有些上下文允许Base64流包含Base64编码方案没有使用的字符,并简单地丢弃它们。然而,Python的解码器是严格的。如果这是问题所在,修复它是一件简单的事情,显式过滤掉无效字符。
在web上下文中,需要注意的是,“数据url”可能是带有某种前缀的base64数据。在解码之前需要丢弃前缀,因为它可能包含对base64有效但不打算被解释为base64的字符。
如果字符串碰巧包含Unicode码位128或更高,则可能会导致
token.encode()
的长度与原始token
不同(因为UTF-8是默认编码),但是,无论如何,这些字符都不会是有效的,因此这不会对问题给予任何特别的见解。