所有字符均可打印的编码方式

基本介绍

「Base64」 是一种基于 64 个可打印字符来表示二进制数据的表示方法。由于 「2⁶ = 64」 ,所以每 6 个比特为一个单元,对应某个可打印字符。(回顾一下,我们之前介绍的 ASCII/Unicode 编码里都有不可打印字符)
体验效果请戳这里 👉:Base64 编码/解码

Base64 相应的索引表如下(这与 ASCII/Unicode 完全不同):
image.png

3 个字节有 24 个比特,对应于 4 个 base64 单元,即 3 个字节可由 4 个可打印字符来表示
相应的转换过程如下图所示:
image.png

编码过程详解

了解完上述的知识,我们以编码 Man 为例,来直观的感受一下编码过程。

找到 ASCII 对应,转换成二进制表示

Man 由 M、a 和 n 这 3 个字符组成,它们对应的 ASCII 码为 77、97 和 110。
image.png

每 6 个比特为一个单元,进行 base64 编码

接着我们以每 6 个比特为一个单元,进行 base64 编码操作,具体如下图所示:
image.png

由图可知,Man (3 字节)编码的结果为 TWFu(4 字节),很明显经过 base64 编码后体积会增加 1/3。Man 这个字符串的长度刚好是 3,我们可以用 4 个 base64 单元来表示。
但如果待编码的字符串长度不是 3 的整数倍时,应该如何处理呢?

处理字节数不能被 3 整除的情况

「如果要编码的字节数不能被 3 整除,最后会多出 1 个或 2 个字节,那么可以使用下面的方法进行处理:先使用 0 字节值在末尾补足,使其能够被 3 整除,然后再进行 base64 的编码。」
以编码字符 A 为例,其所占的字节数为 1,不能被 3 整除,需要补 2 个字节,具体如下图所示:
image.png

由上图可知,字符 A 经过 base64 编码后的结果是 QQ==,该结果后面的两个 = 代表补足的字节数。而最后个 1 个 base64 字节块有 4 位是 0 值。
接着我们来看另一个示例,假设需编码的字符串为 BC,其所占字节数为 2,不能被 3 整除,需要补 1 个字节,具体如下图所示:

image.png

由上图可知,字符串 BC 经过 base64 编码后的结果是 QkM=,该结果后面的 1 个 = 代表补足的字节数。而最后个 1 个 base64 字节块有 2 位是 0 值。

在 JavaScript 中处理解码和编码

在 JavaScript 中,有两个函数被分别用来处理解码和编码 base64 字符串:

  • btoa():该函数能够基于二进制数据 “字符串” 创建一个 base64 编码的 ASCII 字符串。
  • atob(): 该函数能够解码通过 base64 编码的字符串数据。

btoa 使用示例

const name = 'Semlinker';
const encodedName = btoa(name);
console.log(encodedName); // U2VtbGlua2Vy

atob 使用示例

const encodedName = 'U2VtbGlua2Vy';
const name = atob(encodedName);
console.log(name); // Semlinker

对于 atobbtoa 这两个方法来说,其中的 a 代表 ASCII,而 b 代表 Blob,即二进制。

  • 因此 atob 表示 ASCII 到二进制,对应的是解码操作。
  • 而 btoa 表示二进制到 ASCII,对应的是编码操作。

在了解方法中 a 和 b 分别代表的意义之后,在以后的工作中,我们就不会用错了。

应用

Base64 常用于在处理文本数据的场合,表示、传输、存储一些二进制数据,包括 MIME 的电子邮件及 XML 的一些复杂数据。」
MIME 格式的电子邮件中,base64 可以用来将二进制的字节序列数据编码成 ASCII 字符序列构成的文本。使用时,在传输编码方式中指定 base64。使用的字符包括大小写拉丁字母各 26 个、数字 10 个、加号 + 和斜杠 /,共 64 个字符,等号 = 用来作为后缀用途。

其实我们常用的 jwt 技术也应用到了 base64 编码:
image.png

在获取图像内容时也经常用到 base 64:

// 使用 canvas 绘制内容
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d')
...
// 把 canvas 内容转化成 base64 图片形式
const img = canvas.toDataURL()
// do something
// 比如 web 展示、截图分享、微信分享等

图片结构:
data:image/png;base64,xxxxxxxxx

总结

  1. base64 只是一种数据编码方式,目的是为了保障数据的安全传输。
  2. Base64编码会增加数据的大小,大约会增加33%
  3. 标准的 base64 编码无需额外的信息,即可以进行解码,是完全可逆的。因此在涉及传输私密数据时,并不能直接使用 base64 编码,而是要使用专门的对称或非对称加密算法。

参考资料

  1. https://juejin.cn/post/6846687590783909902

specialcoder
2.2k 声望170 粉丝

前端 设计 摄影 文学