cv.cm

知识库 · 文本、数据与安全

什么是 Base64 编码?

阅读约 5 分钟

简短回答

Base64 是一种只用 64 个可打印字符表示二进制数据的方法:A–Z、a–z、0–9、+ 和 /,并用 = 作填充。它把每 3 个字节拆成四组 6 位,每组映射成一个字符,所以「Man」会变成「TWFu」。它让二进制数据可以安全地通过邮件、JSON、URL 等只支持文本的渠道传输,代价是体积增大约 33%。它是编码,不是加密。

打开Base64

Base64 编码原理,一步步拆解

Base64 定义于 RFC 4648。因为 64 = 2⁶,每个输出字符正好携带 6 位,3 个字节(24 位)正好对应 4 个字符。

步骤Man
ASCII 码7797110
二进制(各 8 位)010011010110000101101110
  1. 把 24 位连起来:010011010110000101101110。
  2. 拆成四组 6 位:010011 010110 000101 101110。
  3. 转换为数字:19、22、5、46。
  4. 在字母表中逐个查找(0 = A,25 = Z,26 = a,51 = z,52 = 0,61 = 9,62 = +,63 = /):T、W、F、u。
  5. 结果:TWFu。

用 = 填充

输入长度不是 3 的倍数时,最后一组用零位补齐,并用 = 标记缺少的字节,因此输出长度始终是 4 的倍数。

输入字节数Base64
M1TQ==
Ma2TWE=
Man3TWFu
Hello5SGVsbG8=
é(UTF-8 字节 C3 A9)2w6k=

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–F100%哈希值、颜色代码
Base32A–Z, 2–760%双因素认证密钥
Base64A–Z, a–z, 0–9, +, /33%邮件、Data URL、PEM
Base64urlA–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 开头。

全部知识文章