【深入 Base64】Base64 编码原理(一)

在前端开发中,Base64 的应用场景可是相当多。比如将小图片 Base64 化,直接写入 CSS 文件;与后台通信中,将会被转义的信息 base64 化来防止被转义等等。但是一直不太了解 Base64 的实现原理,这两天特地学习了相关资料,算是比较清楚了,将心得整理成一个系列,以防后面忘记。

什么是 Base64

下面是引用维基百科的一段解释:

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。由于2的6次方等于64,所以每6个比特为一个单元,对应某个可打印字符。三个字节有24个比特,对应于4个Base64单元,即3个字节可表示4个可打印字符。它可用来作为电子邮件的传输编码。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。一些如uuencode的其他编码方法,和之后binhex的版本使用不同的64字符集来代表6个二进制数字,但是它们不叫Base64。

这段解释基本已经很详细了,说出了 Base64 有一下几个特点:

  • 输出的字符范围为 64 个。
  • 将每 3 个字节转换成 4 个字符

 转码规则

  • 把 3 个 8bit 字节变成 4 个 6bit 字符。
  • 每 76 个字节加一个换行符。
  • 最后的结束符也要处理。

Base64 要求把每三个 8Bit 的字节转换为四个 6Bit 的字节,然后把 6Bit 再添两位高位 0,组成四个 8Bit 的字节,也就是说,转换后的字符串理论上将要比原来的长 1/3。 

Base64 编码字符集

码值 字符 码值 字符 码值 字符 码值 字符
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

编码过程

正常情况下就是每 3 个字节编码成 4 个字节,但是,如果最后的字节数不足 3 个字节,则按下面规则进行编码,并且在最后通过加“=”来维持输出 4 个字节。

也就是说,编码后的字符串长度一定是 4 的倍数。

Base64 编码的扩展

Base64 在 URL 中的扩展

标准的 Base64 并不适合直接放在 URL 里传输,因为 URL 编码器会把标准 Base64 中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为 ANSI SQL 中已将“%”号用作通配符。

为解决此问题,可采用一种用于 URL 的改进 Base64 编码,它在末尾填充 '=' 号,并将标准 Base64 中的“+”和“/”分别改成了“-”和“_”,这样就免去了在 URL 编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。

Base64 在正则表达式中的扩展

用于正则表达式的改进 Base64,它将“+”和“/”改成了“!”和“-”,因为“+”,“*”在正则表达式中都具有特殊含义。