前言
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 排版