编码
我们知道,所有的信息最终都表示为一个二进制的字符串,每一个二进制位(bit)有 0 和 1 两种状态。当我们需要把字符 ‘A’ 存入计算机时,我们可以将字符 ‘A’ 用 01000010(这个随便编的)二进制字符串表示,存入计算机;读取时,再将 01000010 还原成字符’A’。那么问题来了,存储时,字符’A’应该对应哪一串二进制数呢,是01000010?或者是 10000000 11110101?说白了,就是需要一个规则。这个规则可以将字符映射到唯一一种状态(二进制字符串),这就是编码。
ASCII
这套编码规则是由美国定制,一共规定了 128 个字符的编码。这 128 个字符(符号),只占用了一个字节(8 bit)的后面 7 位,最前面的 1 位统一规定为 0 。总共才有128个字符编码,一个字节都没有用完,这好像似乎有点太少了。于是乎,就开始压榨最高位,对其为 1 时也进行编码,利用最高位进行编码的方式就称为非 ASCII 编码,如 ISO-8859-1 编码。
Base64是什么?
Base64 严格来说也是一个编码格式,并不是我们常说的 “Base64加密” 。
Base64 的由来
由于历史原因,早前 Email 只被允许传送英文,但随着后来用户的增加,中文、日文等文字的用户也有需求,但是这些字符并不能被服务器或者网关有效的处理,导致邮件出现乱码,因此 Base64 就出现了。随之,Base64 在 URL、Cookie、网页传输少量二进制文件中也有相应的使用。
Base64 的作用
Base64 的作用就是用有限的常规字符(可打印的字符)表示一切数据(各种语言),就如上面说的 email 处理数据。
Base64 工作原理
第一步:Base64 定义每 3 个字节为一组,每个字节占 8 位,那么共有 24 个二进制位。
第二步:将上面的 24 个二进制位每 6 个分为一组,共分 4 组。
第三步:在每组前面添加两个 0,每组由 6 个变为 8 个二进制位,总共 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 | 11 |
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 字符表中的字符原本用 6 个 bit 就可以表示,现在前面添加 2 个 0,变为 8个 bit,会造成一定的浪费。因此,Base64 编码之后的文本,要比原文大约三分之一。
示例说明
第一步:“M”、“a”、”n” 对应的 ASCII 码值分别为 77,97,110,对应的二进制值是01001101、01100001、01101110。如图第二三行所示,由此组成一个 24 位的二进制字符串。
第二步:如图红色框,将 24 位每 6 位二进制位一组分成四组。
第三步:在上面每一组前面补两个 0,扩展成 32 个二进制位,此时变为四个字节:00010011、00010110、00000101、00101110。分别对应的值(Base64 编码索引)为:19、22、5、46。
第四步:用上面的值在 Base64 编码表中进行查找,分别对应:T、W、F、u。因此 “Man”Base64 编码之后就变为:TWFu。
位数不足
上面是按照三个字节来举例说明的,如果字节数不足三个,那么该如何处理?
两个字节:两个字节共16个二进制位,依旧按照规则进行分组。此时总共16个二进制位,每6个一组,则第三组缺少2位,用0补齐,得到三个Base64编码,第四组完全没有数据则用“=”补上。因此,上图中“BC”转换之后为“QKM=”;
一个字节:一个字节共8个二进制位,依旧按照规则进行分组。此时共8个二进制位,每6个一组,则第二组缺少4位,用0补齐,得到两个Base64编码,而后面两组没有对应数据,都用“=”补上。因此,上图中“A”转换之后为“QQ==”;
延伸
上面我们已经看到了 Base64 就是用 6 位(2 的 6 次幂就是 64)表示字符,因此成为Base64。同理,Base32 就是用5位,Base16 就是用 4 位。大家可以按照上面的步骤进行演化一下。
reference
- 本文标题:base64编码
- 本文作者:9unk
- 创建时间:2019-11-26 01:12:38
- 本文链接:https://9unkk.github.io/2019/11/26/base64-bian-ma/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!