前言
Hello 大家好!我是壹甲壹!
在开发中,都使用过 Base64 对小图片进行编码成 data:image/png;base64, xxx... 格式的字符串,优势在于减少请求。
而今天要探讨的是为什么叫 Base64 编码而不叫 Base32 ? 64 是从何而来的?
编码发展史
探究 Base64 如何编码之前,先了解下编码发展史。
1.1 ASCII
ASCII 码由美国人发明,一个字节用来描述一个字符,一共定义了 128 个字符。
不足:只能用于显示现代英语和其他西欧语言
1.2 GBK
对于如何显示汉字,中国在 ASCII 的基础上,扩展出 gb2312, 再到 gbk ,最后到 gb18030 。
同时规定 两个字节描述一个汉字
1.3 Unicode
每个国家都在 ASCII 进行各自的编码扩展,而 Unicode 的出现为每种语言中的每个字符设定了统一并且唯一的二进制编码,Unicode 也被成为 万国码、统一码。
而常见的 UTF-8 是针对Unicode的一种可变长度字符编码,也有 UTF-16, UTF-32。
在 UTF-8 中规定,三个字节描述一个汉字
Base64编码实践
以汉字 甲 为例,默认 utf8 格式,那么就是 3个字节一共 24 位。
1、使用 Buffer.from("甲") 输出汉字的 16 进制表示
Buffer.from("甲")
// <Buffer e7 94 b2>
2、将其每个字节转换成 二进制
console.log((0xe7).toString(2))
console.log((0x94).toString(2))
console.log((0xb2).toString(2))
// 11100111 10010100 10110010
3、按照规定,将 24 位变成 4 个字节,每个字节不够 8 位的前置补零
111001111001010010110010
// 拆成4个字节
111001 111001 010010 110010
// 前置补零
00111001 00111001 00010010 00110010
4、转换成 4 个字节后,每个字节的前 2 位都是 0 ,所以取值范围是 00000000 ~ 00111111 ,后 6 位正好
是0~2^6-1 , 一共 64 个,所以才会叫 Base64
5、将二进制的 4 个字节转换成 10 进制,
console.log(parseInt("00111001", 2))
console.log(parseInt("00111001", 2))
console.log(parseInt("00010010", 2))
console.log(parseInt("00110010", 2))
// 57 57 18 50
6、Base64 存在一个取值表
let str = `ABCDEFGHIGKLMNOPQRSTUVWXYZ`
str += str.toLocaleLowerCase()
str += '0123456789+/'
7、从取值表中找出 57 57 18 50 几位对应的字符了
str[57] + str[57] + str[18] + str[50]
"55Sy"
8、我们使用在线工具 Base64 解码 对 55Sy 解码输出的正好是汉字 甲
总结
Base64会将一个汉字由 3 个字节转成 4 个字节,所以转换后体积变大 1/3- 大文件并不适合
Base64编码 - 不同文件有着不同的
Base64编码风格(对照表), 图片有字节的规则表,不够位会进行补等于号。

本文使用 mdnice 排版