跳到主要内容

Base64 的原理及优缺点

面试速答(30 秒版 TL;DR)

  • Base64 不是加密(encryption),而是编码(encoding):把二进制数据用一组“可打印字符”表示,方便在只支持文本的通道里传输/存储。
  • 核心规则:每 3 个字节(24 bit)编码成 4 个字符(4 * 6 bit),所以体积通常膨胀约 4/3(约 33%);不足 3 字节用 = 做填充(padding)。
  • 常见字母表:A-Z a-z 0-9 + /(共 64 个字符);URL 场景常用 Base64URL(把 + / 换成 - _,并可能去掉 =)。

心智模型:6 bit “查表编码”

把 Base64 记成一句话就够用:

  • 把连续的二进制流按 6 bit 切块,每块用一个“字母表”字符表示。

为什么是 6 bit?

  • 2^6 = 64,刚好对应 64 个字符,既能覆盖常见文本传输,又比十六进制(hex,4 bit/字符)更省空间。

Base64 怎么编码:关键步骤(会说清即可)

1)3 字节 -> 4 字符

  • 输入:3 字节 = 24 bit
  • 输出:4 组 * 6 bit = 24 bit

因此膨胀比例:

  • n 字节编码后长度约为 ceil(n / 3) * 4
  • 理论膨胀比约为 4 / 3 = 1.333...(约 33%)

2)= 填充(padding)规则

当最后不足 3 字节时:

  • 剩 1 字节:产出 2 个 Base64 字符,后面补 ==
  • 剩 2 字节:产出 3 个 Base64 字符,后面补 =

面试官追问“为什么要 =”时,你可以答:

  • = 让输出长度固定为 4 的倍数,便于解码端确定末尾真实数据长度。

优点(为什么还会用)

  • 兼容性强:几乎所有语言/环境都有实现。
  • 适合“只能放文本”的通道:例如 JSON、XML、某些配置文件、日志、早期邮件传输、以及前端 data: URL。
  • 可直接嵌入:在 HTML/CSS 里内联小资源(小图标、很小的 SVG 等)很方便。

缺点(为什么经常不推荐滥用)

  • 体积膨胀:约 33% 的纯编码开销;放进 data: URL 还会额外加上 data:image/...;base64, 前缀。
  • CPU 与内存开销:编码/解码都需要额外计算;在 JS 里把大文件转成 Base64 字符串容易造成内存峰值与卡顿。
  • 不是安全方案:可逆、无密钥,不能替代加密/签名;也不提供完整性校验。
  • 缓存粒度变差(前端常见):把图片 Base64 内联进 CSS/JS,资源缓存从“图片单独缓存”退化为“CSS/JS 变更就全量失效”。

前端里常见的“正确打开方式”

  • 小体积、频繁使用、希望减少请求数:可以考虑 Base64 内联(但在 HTTP/2/3 下收益通常变小)。
  • 大图、可复用资源:优先独立文件 + CDN 缓存;要预览本地文件优先 URL.createObjectURL() 而不是 Base64。

典型题 & 标准答法

Q1:Base64 为什么会变大约 1/3?

:因为 3 字节(24 bit)被编码成 4 个字符,每个字符表示 6 bit。4 / 3 = 1.333...,所以约膨胀 33%。

Q2:Base64 是加密吗?能“防抓包”吗?

:不是。Base64 只是编码,可逆;抓到 Base64 字符串的人可以直接解码回原文。要安全需要 HTTPS + 业务侧加密/签名。

Q3:Base64 和 hex(十六进制)比有什么差异?

  • hex:4 bit/字符,体积约膨胀 100%(1 字节 -> 2 个 hex 字符)
  • Base64:6 bit/字符,体积约膨胀 33%(更省)

易错点/坑

  • 把 Base64 当“加密/脱敏”:这是错的。
  • 对大文件做 Base64:容易内存爆、页面卡顿、传输更慢。
  • URL 场景直接用标准 Base64:+ / = 可能需要额外转义,通常应使用 Base64URL。

速记要点(可背诵)

  • Base64:编码不是加密3 字节 -> 4 字符;不足补 =;体积约 +33%
  • 前端:小资源内联可考虑;大资源别用,缓存与性能都吃亏。