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%。 - 前端:小资源内联可考虑;大资源别用,缓存与性能都吃亏。