在前端开发中,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,它将“+”和“/”改成了“!”和“-”,因为“+”,“*”在正则表达式中都具有特殊含义。