在尝试使用Incorrect padding
函数在python中解码BASE32字符串时,出现base64.b32decode()
错误。我认为我的填充正确。我在哪里弄错了?
import base64
my_string=b'SOMESTRING2345'
print(my_string)
print("length : "+str(len(my_string)))
print("length % 8 : "+str(len(my_string)%8))
p_my_string = my_string+b'='*(8-(len(my_string)%8))
print("\nPadded:\n"+str(p_my_string))
print("length : "+str(len(p_my_string)))
b32d = base64.b32decode(p_my_string)
print("\nB32 decode : " + str(b32d))
print("length : " + str(len(b32d)))
运行此代码会让我
b'SOMESTRING2345'
length : 14
length % 8 : 6
Padded:
b'SOMESTRING2345=='
length : 16
---------------------------------------------------------------------------
Error Traceback (most recent call last)
<ipython-input-2-9fe7cf88581a> in <module>()
10 print("length : "+str(len(p_my_string)))
11
---> 12 b32d = base64.b32decode(p_my_string)
13 print("\nB32 decode : " + str(b32d))
14 print("length : " + str(len(b32d)))
/opt/anaconda3/lib/python3.6/base64.py in b32decode(s, casefold, map01)
244 decoded[-5:] = last[:-4]
245 else:
--> 246 raise binascii.Error('Incorrect padding')
247 return bytes(decoded)
248
Error: Incorrect padding
但是,如果将my_string
更改为b'SOMESTRING23456'
,我的代码将与输出完美配合-
b'SOMESTRING23456'
length : 15
length % 8 : 7
Padded:
b'SOMESTRING23456='
length : 16
B32 decode : b'\x93\x98IN(i\xb5\xbew'
length : 9
答案 0 :(得分:2)
没有合法的14个字符的base32字符串。模数8之外的任何余数只能为2、4、5或7个字符,因此填充必须始终为6、4、3或1个=
字符,其他任何长度均无效。由于剩余的6个字符不是合法的base32编码,因此base32decode()
函数除了拒绝使用无效的5
填充字符(而不是有效的=
填充字符)之外,无法执行任何操作。
base32字符编码5位,并且字节始终为8位长。这意味着您不需要为5个字节的倍数输入填充(5乘8 == 40位,可以干净地编码8个字符)。
因此对5的倍数上的任何余数进行编码
14个字符将保留70位,这是8字节(64位),其中有6位备用,因此字符14将没有任何意义!
因此,对于任何剩余的1、3或6个字符的base32字符串,无论您添加多少个Incorrect padding
字符,您都将始终遇到=
异常。
请注意,余数的最后一个字符编码的位数有限,因此也将落入特定范围内;对于2个字符(编码1个字节),第二个字符仅对3位进行编码,最后2位保留为0,因此只能使用A,E,I,M,Q,U,Y和4(因此,第4个字符base32字母,AZ + 2-7)。由于有4个字符,最后一个字符仅代表一位,因此只有A和Q是合法的。 5个字符留下1个冗余位,因此可以使用第二个字符(A,C,E等),而对于7个字符和3个冗余位,则可以使用第8个字符(A,I,Q,Y)。
解码器可以选择在最后一个位置接受所有可能的base32字符,而只是掩盖仍然需要的位,因此对于2个字符,B
或7
或其他任何一个无效字符仍然可以导致成功解码,但是AA
,AB
,AC
和AD
之间没有区别,所有4个仅使用前3位第二个字符中的第一个字符和所有4个序列解码为十六进制值0x00
。