Skip to content

base64

base64模块用于在原始二进制数据和base64编码后的只含ASCII字符串的二进制数据之间转换.

注意
  • 输入: 原始二进制数据/二进制流
  • 输出: base64编码后的二进制数据/二进制流

目的

某些场合可能不能传输或者存储原始二进制流.

例子

比如, 如果一个传输协议是基于ASCII文本的, 那么它就无法传输原始二进制流, 原始二进制中可能会出现被当作控制字符处理的部分, 引起传输失败. 比如SMTP协议, HTTP协议中的URL也是纯文本的, 不能直接放原始二进制数据. 如果使用base64对原始二进制进行编码之后传输, 然后在接收方使用base64进行解码, 就可以解决这个问题.

原理

  1. 准备一个包含64个ASCII字符的数组
  2. 对原始二进制数据进行处理, 每3个字节为一组, 一组总共24bit
  3. 将每一组划分为4个小组, 每个小组正好6bit
  4. 每6bit都能对应上一个字符, 一个字符占用1个字节, 所有的6bit都可以查表得到一个字符
  5. 组合起来的字符串就是编码后的二进制数据

可以看到, 3个字节的原始二进制数据到最后变成了4个字节的二进制数据, 占用的空间增加了33%.

Tip

如果要编码的原始二进制数据不是3的倍数, 而是缺少了1个或者2个字节, base64会用\x00字节在末尾补足, 然后编码, 完成之后特别的在末尾加上1个或者2个=号, 表示缺少多少个字节. 解码的时候, 会根据这些信息得到原始的二进制流.

这64个字符的数组是可以自定义的, 这样第4步中6bit对应的字符就是我们自定义的字符.

注意

标准的base64编码的64个字符的数组中含有"/"和"+", 在编码二进制数据之后有的6bit字符可能对应到"/"或者"+"上, 这会导致编码之后的二进制数据可能无法作为URL中的参数, 所以有一种URL安全的base64编码, 其实就是在数组中将+/分别变成-_.

例子
>>> base64.b64encode(b'i\xb7\x1d\xfb\xef\xff')
b'abcd++//'
>>> base64.urlsafe_b64encode(b'i\xb7\x1d\xfb\xef\xff')
b'abcd--__'
>>> base64.urlsafe_b64decode('abcd--__')
b'i\xb7\x1d\xfb\xef\xff'
Tip

由于=字符也可能会出现在编码中, 但是=会在URL, Cookie中造成歧义, 所以很多base64编码后会把=去掉. 解码过程中会把=加上, 使长度变为4的倍数, 就可以正常解码了.


  1. 为什么要使用base64编码,有哪些情景需求?—知乎. (n.d.). Retrieved June 19, 2024, from https://www.zhihu.com/question/36306744 

  2. Base64. (n.d.). Retrieved June 19, 2024, from https://www.liaoxuefeng.com/wiki/1016959663602400/1017684507717184