你的数据 100% 私密 —— Base64 的编码和解码全部在你的设备上完成。
Base64 是一种用 64 个 ASCII 字符(A–Z、a–z、0–9,再加上 + 和 /)把二进制数据表示成纯文本的方法。它让图片、密钥、电子邮件附件这类二进制数据,能安全地通过为文本而设计的系统。它是编码,不是加密。
Base64 使用一组固定的 64 个字符的字母表。0 到 63 之间的每个值都恰好对应其中一个字符,任何 3 个字节的二进制数据也因此变成 4 个可读的字符:
| 数值 | 字符 | |
|---|---|---|
| 0–25 | A–Z | 26 个大写字母 |
| 26–51 | a–z | 26 个小写字母 |
| 52–61 | 0–9 | 10 个数字 |
| 62–63 | + / | 2 个符号 |
只有 "=" 符号是例外。它是填充,并非那 64 个数值之一,只用来补齐最后一个块。
你几乎一定已经见过它了。只要二进制数据需要藏在文本里传递,Base64 就会出现:
那个 data URI 技巧长这样,这串长字符串就是整张图片:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />早期的网络协议是为文本、而非原始字节设计的。ASCII 使用 7 个位、128 个字符,用于英文绰绰有余,但对二进制却不行。有些系统会破坏控制字符,或改写换行(把 LF 改成 CR + LF),在传输途中悄悄损坏图片与音频。
Base64 只输出每个系统早已共同认可的字符,借此避开了上述所有问题。Base16 与 Base32 用更小的字母表做同样的事,但 Base64 在保持安全的同时,每个字符能塞进更多数据。这正是它胜出的原因。
整套方法就是一个思路的重复:取 3 个字节(24 个位),把它们重新切成 4 组各 6 个位,再用字母表查出每 一组对应的字符。我们用 "Logto" 这个词手动编码一次。
步骤 1. 把每个字符变成 8 位的二进制:
| 字符 | ASCII 码 | 二进制 |
|---|---|---|
| L | 76 | 01001100 |
| o | 111 | 01101111 |
| g | 103 | 01100111 |
| t | 116 | 01110100 |
| o | 111 | 01101111 |
步骤 2. 取前 3 个字节 "Log",把这同样的 24 个位重新切成 4 组各 6 个位:
步骤 3. 把每组 6 个位当成数字来读,再用这个数字查字母表:
| 6 位分 组 | 数值 | Base64 字符 |
|---|---|---|
| 010011 | 19 | T |
| 000110 | 6 | G |
| 111101 | 61 | 9 |
| 100111 | 39 | n |
"Logto" 有 5 个字节,不是 3 的倍数。最后两个字节 "to" 会切成 6 + 6 + 4。把最后 4 个位用 0 补成一组 6 个位,再加上一个 "=",补齐这个 4 字符的块:
把各块拼起来:
"Logto" → TG9ndG8=每种语言都内置了它。在 Node.js 中:
const text = 'Logto';
const base64 = Buffer.from(text).toString('base64');
console.log(base64); // TG9ndG8=从这个过程会得出三条值得记住的规律:
当二进制数据必须通过只能处理文本的通道时,就用 Base64:
你得到的回报:
标准的 Base64 依赖三个会跟 URL、查询字符串、文件名运作方式相冲突的字符:+、/,以及 = 填充。把普通的 Base64 字符串直接放进链接,它可能会以不易察觉的方式出错:
你可以对它们做百分号编码(+ 变成 %2B、/ 变成 %2F、= 变成 %3D),但这会让字符串变长,也很容易不小心重复编码。
Base64URL(RFC 4648 §5)从根源解决了这个问题:把 + 换成 -、把 / 换成 _,并去掉 = 填充。这样的结果可以直接放进 URL、查询参数或文件名,完全不用转义。你会在 URL、文件名,以及许多 Web API 中看到它。
const base64 = 'TG9ndG8=';
const urlSafe = base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
console.log(urlSafe); // TG9ndG8Base64 只是一种表示方式,不是天上掉下来的好处。请记住三件事:
不是。它是使用公开字母表的可逆编码,任何人都能立即解码,完全不增加任何保密性。请改为加密敏感数据。
Base64 把每 3 个字节变成 4 个字符,所以编码后的形式总是比原始字节大约大三分之一。
它们是让输出保持在 4 个字符倍数的填充。一个 "=" 代表输入剩 2 个字节,两个 "=" 代表剩 1 个,没有 "=" 代表长度本来就是 3 个字节的倍数。
Base64URL 是使用 URL 与文件名安全字母表的同一种编码:- 和 _ 取代 + 和 /,而 = 填充通常会被去掉。它常见于 URL、文件名,以及许多 Web API。
任何二进制数据都可以:图片、PDF、密钥、可执行文件。Base64 处理的是原始字节,所以原本的内容类型并不重要。
不会。编码与解码完全在你的浏览器中执行。你粘贴的任何内容都不会被 上传或记录。