知识库 · 文本、数据与安全
什么是 Base64 编码?
简短回答
Base64 是一种只用 64 个可打印字符表示二进制数据的方法:A–Z、a–z、0–9、+ 和 /,并用 = 作填充。它把每 3 个字节拆成四组 6 位,每组映射成一个字符,所以「Man」会变成「TWFu」。它让二进制数据可以安全地通过邮件、JSON、URL 等只支持文本的渠道传输,代价是体积增大约 33%。它是编码,不是加密。
打开Base64Base64 编码原理,一步步拆解
Base64 定义于 RFC 4648。因为 64 = 2⁶,每个输出字符正好携带 6 位,3 个字节(24 位)正好对应 4 个字符。
| 步骤 | M | a | n |
|---|---|---|---|
| ASCII 码 | 77 | 97 | 110 |
| 二进制(各 8 位) | 01001101 | 01100001 | 01101110 |
- 把 24 位连起来:
010011010110000101101110。 - 拆成四组 6 位:
010011010110000101101110。 - 转换为数字:19、22、5、46。
- 在字母表中逐个查找(0 = A,25 = Z,26 = a,51 = z,52 = 0,61 = 9,62 = +,63 = /):T、W、F、u。
- 结果:
TWFu。
用 = 填充
输入长度不是 3 的倍数时,最后一组用零位补齐,并用 = 标记缺少的字节,因此输出长度始终是 4 的倍数。
| 输入 | 字节数 | Base64 |
|---|---|---|
M | 1 | TQ== |
Ma | 2 | TWE= |
Man | 3 | TWFu |
Hello | 5 | SGVsbG8= |
é(UTF-8 字节 C3 A9) | 2 | w6k= |
n 字节的数据编码后长度为 4 × ceil(n ÷ 3) 个字符。1 MB 的文件会变成约 1.33 MB 的文本;MIME 邮件还会每 76 个字符插入一个换行,开销再略高一些。
Base64 用在哪里
- 邮件附件:最初的邮件系统只能传输 7 位文本,所以 MIME 用 Base64 编码文件。
- Data URL:内嵌在 HTML 或 CSS 中的小图片,写作
data:image/png;base64,iVBORw0KGgo...。 - 需要传输图片、密钥或证书等二进制数据的 JSON 和 XML 接口。
- JSON Web Token(JWT),其头部和载荷都是经过 Base64url 编码的 JSON。
- TLS 证书和密钥的 PEM 文件,用
-----BEGIN CERTIFICATE-----等行包裹 Base64 内容。 - HTTP Basic 认证,发送经过 Base64 编码的
username:password。
把图片内嵌为 Data URL 能省一次网络请求,但体积会增加 33%,也无法单独缓存,所以通常只适合非常小的图片。
Base64 与 Base64url 及其他编码
标准 Base64 使用 + 和 /,这两个字符在 URL 和文件名中有特殊含义。同一 RFC 中的 URL 安全变体把它们换成 - 和 _,并且常常省略 = 填充。
| 编码 | 字符 | 体积开销 | 用途示例 |
|---|---|---|---|
| Base16(十六进制) | 0–9, A–F | 100% | 哈希值、颜色代码 |
| Base32 | A–Z, 2–7 | 60% | 双因素认证密钥 |
| Base64 | A–Z, a–z, 0–9, +, / | 33% | 邮件、Data URL、PEM |
| Base64url | A–Z, a–z, 0–9, -, _ | 33% | JWT、URL 参数 |
常见错误
- 文本必须先转换成字节,通常用 UTF-8。在 JavaScript 中,
btoa()遇到 Latin-1 以外的字符(如 emoji 或中文)会报错,除非先把字符串按 UTF-8 编码。 - 混用标准字母表和 URL 安全字母表会导致解码出错;使用标准解码器前,先把
-和_替换成+和/。 - 缺少填充可能导致严格的解码器失败;补上
=,直到长度是 4 的倍数。 - 邮件式编码产生的换行,在某些解码器接受字符串前必须先去掉。
常见问题
为什么 Base64 会让数据变大?
每 3 个字节变成 4 个字符,而每个字符又要占用一个完整字节,所以输出比输入大约 33%。
Base64 安全吗?
不安全。它什么也没隐藏,解码不需要任何密钥。要保护数据请用 AES 等真正的加密算法,Base64 只用来把加密结果以文本形式传输。
Base64 末尾的 = 是什么意思?
是填充。一个 = 表示最后一组只有 2 个字节,== 表示只有 1 个字节。
怎样识别一个 Base64 字符串?
它只包含字母、数字、+ 和 /(或 - 和 _),长度通常是 4 的倍数,末尾可能有一到两个 = 号。以 eyJ 开头的字符串往往是 Base64 编码的 JSON,因为以 {" 开头的 JSON 文本编码后正好以 eyJ 开头。