base64 我终于学废了

129 阅读4分钟

base64 是什么

Base64 是一种二进制到文本的编码方式。而且编码出的字符串只包含 ASCII 基础字符。

为什么叫 base64

因为它的编码基于(Base)64个字符。可能也会看到填充字符=

字符如下所示:

  • A-Z 26个
  • a-z 26个
  • 0-9 10个
  • + 1个
  • / 1个

什么要使用这 64 个字符呢

在计算机中,所有的数据在存储和运算时都要使用二进制数表示,而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就出台了 ASCII 编码。

20190920120544393.png

这样一看,好像没问题了,如果一切都这么顺利,就没 base64 什么事了。在 ASCII 码中规定,0到31、127 这 33 个字符属于控制字符,32到126 这 95 个字符属于可打印字符

Base64 一般用于在HTTP协议下传输,由于HTTP协议是文本协议,所以在HTTP协议下传输二进制数据需要将二进制数据转换为字符数据。然而直接转换是不行的。因为网络传输只能传输可打印字符。

对于控制字符,信息在网络的传递中,有可能会被路由器等自作主张的处理掉,从而导致数据的丢失。

base64怎么转换

先看 base64 对于的索引与数值

v2-5d96b9e86e3b70ee346cffe90cbd7b6d_1440w.webp

64 个字符,如果将索引转换为对应的二进制数据的话需要至多6个Bit,然而 ASCII 码需要8个Bit来表示,那么怎么使用6个Bit来表示8个Bit的数据呢?6个Bit当然不能存储8个Bit的数据,但是我们都知道

4 * 6 = 3 * 8

我们可以将 3个 ASCII 码 转化为 4 个 base64 码,这也就解释了为什么 base64 编码之后体积会变大的原因了。

我们举个例子, 假设有字符串“abc", 我们要对其进行base64编码,最后结果会是什么呢?

原始字符abc
ascii 编码979899
二进制位011000010110001001100011
每 6 bit 为一组011000010110001001100011
高位补 000011000000101100000100100100011
对应的 base64 索引2422935
对应的 base64 字符YWJj

使用 Base64 进行编码,大致可以分为 4 步

  1. 将原始数据每三个字节作为一组,每个字节是8个bit,所以一共是 24 个 bit
  2. 将 24 个 bit 分为四组,每组 6 个 bit
  3. 在每组前面加补 00,将其补全成四组8个bit 到此步,原生数据的3个字节已经变成4个字节了,增大了将近30%
  4. 根据Base64码表得到扩展后每个字节的对应符号(见上图)

那么末尾的 = 是如何出现的呢?

通过上面的我们知道了Base64编码过程是3个字符一组的进行,如果原文长度不是3的倍数怎么办呢?

它不够3个,那么只能在编码后的字符串中补=了。缺一个字符补一个,缺两个补两个即可,所以有时候你会看见base64字符串结尾有1个或者2个=

js 中的 base64

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

atob() ASCII to Base64 函数能够解码通过 base-64 编码的字符串数据

btoa() Base64 to ASCII 函数能够从二进制数据“字符串”创建一个 base-64 编码的 ASCII 字符串。

window.btoa('abc') // 'YWJj'
window.atob('YWJj') // 'abc'

如果有字符超出了 8 位 ASCII 编码的字符范围时,在大多数的浏览器中对 Unicode 字符串调用 window.btoa 将会造成一个 Character Out Of Range 的异常,需要处理一下。处理方法在这里呢(developer.mozilla.org/zh-CN/docs/…

window.btoa('你好帅') // Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

最后:你还认为我是加密算法嘛

参考资料