Base64 为什么让体积涨三分之一
先说结论
Base64 不是压缩,是编码。它不会让数据变小,反而固定变大 33.3%。
一张 300 KB 的图片转成 Base64 大约 400 KB。这不是哪个库写得差,是这套编码的数学比例决定的。
那个 4/3 是怎么来的
Base64 的字符集只有 64 个字符:
A-Z a-z 0-9 + /
64 = 2^6,所以一个字符携带 6 个比特。
而原始数据是按 8 比特(1 字节) 组织的。
于是:
3 个字节 = 3 × 8 = 24 比特
24 比特 ÷ 6 比特每字符 = 4 个字符
每次拿 3 个字节,换成 4 个字符。 比例固定是 4:3。
体积变化 = 4/3 ≈ 1.333,也就是多出 33.3%。
反过来算也一样:400 KB 的 Base64 数据,解码后正好约 300 KB。
为什么非得这么干
因为有些通道只认文本,不认任意字节。
比如:
- JSON 里放不下一段原始二进制(那是非法字符)
- 邮件协议(SMTP)历史上只保证 7 位 ASCII 安全
- URL 里放二进制字节会被转义得面目全非
- XML、配置文件这类必须是合法文本的容器
Base64 干的事就是:把「任意 8 位字节」翻译成「64 个安全字符」,牺牲体积换通用性。
那个 = 是干吗的
原始数据长度不一定是 3 的倍数。末尾凑不满的时候:
原始长度 | Base64 长度 | 填充
3 的倍数 | 正好 4 的倍数 | 无
除以 3 余 1 | 补 == | 2 个等号
除以 3 余 2 | 补 = | 1 个等号
比如 "a"(1 字节)编码后是 YQ==,"ab"(2 字节)是 YWI=。
= 不携带信息,只是补齐长度,方便解码器按 4 个一组切分。
什么时候用是划算的,什么时候是纯亏
划算:
- 小图标直接内联进 CSS / HTML,省一次请求(几十字节的图标,多 33% 无所谓)
- 需要在 JSON 里传一小段二进制
- 配置里放密钥文件、证书
纯亏:
- 大文件。1 GB 的视频转 Base64 变成 1.33 GB,编码解码还要额外吃 CPU 和内存
- 本来就是文本的数据。文本转 Base64 毫无意义,只会变大
- 已经压缩过的数据(jpg、png、zip)。Base64 不改变熵,压不动,只是纯粹变大
第二条最容易被忽略:给一句普通的英文句子做 Base64,体积一样涨 33%,因为它本来就是 8 位字节。
一个常见的坑:URL 里不能直接用
标准 Base64 用的 + 和 / 在 URL 里有特殊含义,= 也可能出问题。
所以有 URL-safe Base64:把 + 换成 -,/ 换成 _,去掉填充的 =。
import base64
base64.urlsafe_b64encode(b'\xfb\xff') # b'-_8='
base64.b64encode(b'\xfb\xff') # b'+/8='
把标准 Base64 塞进 URL 参数里,+ 会被解码成空格——这种 bug 很隐蔽,往往要等到某个特定输入的 ID 才复现。
顺带提一个容易混淆的东西
Base64 不是加密。它是公开的、可逆的、无密钥的。任何看到 Base64 串的人都能解出来。
把敏感信息做一次 Base64 就以为安全了,是很常见的误解——它只是换了个写法,内容一个比特都没少。
落一句
Base64 的本质是用 33% 的体积,换「任何通道都能安全传输」。
记住 3 字节换 4 字符这个比例,你就永远不会奇怪它为什么变大。
- 点赞
- 收藏
- 关注作者
评论(0)