Base64 是一种基于 64 个可打印字符来表示二进制数据的表示方法。由于 \(2^6=64\) ,所以每 6 个比特为一个单元,对应某个可打印字符。3 个字节有 24 个比特,对应于 4 个 Base64 单元,即 3 个字节可由 4 个可打印字符来表示。 ——维基百科

编码原理

标准 Base64 里的 64 个可打印字符是 A-Za-z0-9+/1,分别依次对应索引值 0-63。索引表如下:

数值字符数值字符数值字符数值字符
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P31f47v63/

编码时,每 3 个字节一组, 即 8bit*3=24bit,按照 6bit 一组重新划分成 4 组,代表一个编码后的索引值。举个例子:

原文cat
ASCII 码9997116
原 8 位二进制011000110110000101110100
折算 6 位二进制011000110110000101110100
索引2454552
BASE64Y2F0

可以看到 cat 编码后变成了 Y2F0。用 Python 验算一下:

1
2
import base64
base64.b64encode(b'cat')
1
b'Y2F0'

如果待编码内容的字节数不是 3 的整数倍,那需要进行一些额外的处理:

  • 如果最后剩下 2 个字节(16bit),那么将补 2 个 0 位(凑成 18bit),编码成 3 个 Base64 字符,然后补一个 =。
原文ca
ASCII 码9997
原 8 位二进制0110001101100001
折算 6 位二进制011000110110000100
索引24544
BASE64Y2E=
1
2
import base64
base64.b64encode(b'ca')
1
b'Y2E='
  • 如果最后剩下 1 个字节(8bit),那么将补 4 个 0 位(凑成 12bit),编码成 2 个 Base64 字符,然后补两个 =。
原文c
ASCII 码99
原 8 位二进制01100011
折算 6 位二进制011000110000
索引2448
BASE64Yw==
1
2
import base64
base64.b64encode(b'c')
1
b'Yw=='

  1. 除了标准 Base64 之外,还有一些其它的 Base64 变种。比如在 URL 的应用场景中,因为标准 Base64 索引表中的 / 和 + 会被 URLEncoder 转义成 %XX 形式,但 % 是 SQL 中的通配符,直接用于数据库操作会有问题。此时可以采用 URL Safe 的编码器,索引表中的 /+ 被换成 -_。 [return]