【Python】base64解码报错 Incorrect padding

情景:获取 ID 时进行加密后,放在url中进行传参,传回时,进行解密,在解密环节出现报错:Incorrect padding   排查发现,报错的原因有两个

原因一:

有可能是python base64库编码规则不太统一导致的;解决办法就是对base64解码的string补齐等号就可以了; python中base64串的长度需为4的整数倍,故对长度不为4整数倍的base64串需要用"='补足

解决办法:   python binascii.Error: Incorrect padding

原因二:

由于标准的Base64编码后可能出现字符+/,在URL中就不能直接作为参数,

所以又有一种"url safe"的base64编码,其实就是把字符+/分别变成-_

解决办法:

在补全位数的基础上:

base64.encodebytes(encrypt_aes)     换成      base64.urlsafe_b64encode(encrypt_aes)

base64.decodebytes(encrypt_aes)     换成      base64.urlsafe_b64decode(encrypt_aes)


参考:

base64转码过程

先说一下转换过程,详细的可以参考阮一峰廖雪峰博客

所谓Base64,就是说选出64个字符----小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"(再加上作为垫字的"=",实际上是65个字符)----作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。

具体来说,转换方式可以分为四步。

第一步,将每三个字节作为一组,一共是24个二进制位。

第二步,将这24个二进制位分为四组,每个组有6个二进制位。

第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节。

第四步,根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。

  0 A  17 R   34 i   51 z

  1 B  18 S   35 j   52 0

  2 C  19 T   36 k   53 1

  3 D  20 U   37 l   54 2

  4 E  21 V   38 m   55 3

  5 F  22 W   39 n   56 4

  6 G  23 X   40 o   57 5

  7 H  24 Y   41 p   58 6

  8 I   25 Z   42 q   59 7

  9 J  26 a   43 r   60 8

  10 K  27 b   44 s   61 9

  11 L  28 c   45 t   62 +

  12 M  29 d   46 u   63 /

  13 N  30 e   47 v

  14 O  31 f   48 w   

  15 P  32 g   49 x

  16 Q  33 h   50 y

因为,Base64将三个字节转化成四个字节,因此Base64编码后的文本,会比原文本大出三分之一左右。

Base64笔记 - 阮一峰的网络日志

如果要编码的二进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?Base64用\x00字节在末尾补足后,再在编码的末尾加上1个或2个=号,表示补了多少字节,解码的时候,会自动去掉。

base64 - 廖雪峰的官方网站

Incorrect padding错误

谷歌找到答案 ,说是有可能去掉了编码后的等号,可以手动加上,解决方式如下:

def decode_base64(data):
    """Decode base64, padding being optional.

    :param data: Base64 data as an ASCII byte string
    :returns: The decoded byte string.

    """
    missing_padding = len(data) % 4
    if missing_padding != 0:
        data += b'='* (4 - missing_padding)
    return base64.decodestring(data)

我试了试,其实还是同样的错误,看来并不是等号的问题。

继续尝试,又有人说可能是末尾多了字符,可尝试去掉,方法如下:

lens = len(strg)
lenx = lens - (lens % 4 if lens % 4 else 4)
try:
    result = base64.decodestring(strg[:lenx])
except etc

我又试了试,还是不行~看来也不是这个问题

再往下看,看到了这个

Update 2: It is possible that the encoding has been done in an url-safe manner. If this is the case, you will be able to see minus and underscore characters in your data, and you should be able to decode it by using base64.b64decode(strg, '-_')

意思是如果你解码的是url(咦,我就是处理url),可以这么尝试

base64.b64decode(strg, '-_')

试了一下,然也。

那么为什么会出现这种情况呢?继续查看原因,终于找到了:

由于标准的Base64编码后可能出现字符+/

在URL中就不能直接作为参数,

所以又有一种"url safe"的base64编码,其实就是把字符+/分别变成-_

base64 - 廖雪峰的官方网站

然后,我们这个问题又有另外一个解决方式了:

base64.urlsafe_b64decode(base64_url)

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该错误通常是由于加密数据的base64编码中存在无效的填充字符导致的。解决方法是将编码数据的填充字符删除或添加正确的填充字符,使其长度变为4的倍数。 以下是一些可能的解决方法: 1. 删除填充字符 可以尝试删除编码数据的填充字符,例如,将"=="或"="删除。这可能会导致编码数据的长度不为4的倍数,因此需要在解码之前添加正确的填充字符,使其长度变为4的倍数。 示例代码: ``` import base64 # 编码数据 data = b'hello world' encoded_data = base64.b64encode(data).decode('utf-8') # 删除填充字符 encoded_data = encoded_data.replace('=', '') # 添加正确的填充字符 padding = len(encoded_data) % 4 if padding == 1: encoded_data += '===' elif padding == 2: encoded_data += '==' elif padding == 3: encoded_data += '=' # 解码数据 decoded_data = base64.b64decode(encoded_data.encode('utf-8')) print(decoded_data) ``` 2. 添加正确的填充字符 如果编码数据的长度不为4的倍数,则可以添加正确的填充字符,使其长度变为4的倍数。 示例代码: ``` import base64 # 编码数据 data = b'hello world' encoded_data = base64.b64encode(data).decode('utf-8') # 添加正确的填充字符 padding = len(encoded_data) % 4 if padding == 1: encoded_data += '===' elif padding == 2: encoded_data += '==' elif padding == 3: encoded_data += '=' # 解码数据 decoded_data = base64.b64decode(encoded_data.encode('utf-8')) print(decoded_data) ``` 3. 使用其他库解码数据 如果以上方法仍然无法解决问题,可以尝试使用其他库解码数据,例如,使用cryptography库的base64解码函数。 示例代码: ``` from cryptography.hazmat.primitives import base64 # 编码数据 data = b'hello world' encoded_data = base64.b64encode(data).decode('utf-8') # 解码数据 decoded_data = base64.b64decode(encoded_data.encode('utf-8')) print(decoded_data) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值