Base64 的原理
Base64 的字母表包含 A-Z、a-z、0-9 以及 +、/ 共 64 个字符(另有 = 作填充)。编码时把输入按 3 字节分组共 24 位,重排为 4 个 6 位值,每个值查表得到一个字符,因此输出长度是输入的 4/3 倍、并向上取整到 4 的整数倍。它的价值在于让任意二进制数据安全通过只接受文本的通道:邮件、JSON 字段、HTTP 头、配置文件、数据 URI。它不提供任何保密性或压缩效果。
基本信息
| 字母表 | A-Z、a-z、0-9、+、/ 共 64 个字符,= 为填充 |
|---|---|
| 分组方式 | 3 字节(24 位)拆为 4 个 6 位组 |
| 输出长度 | 约为输入的 4/3,恒为 4 的倍数 |
| 是否加密 | 否,只是编码,可被任何工具立即还原 |
| 典型标准 | RFC 4648 定义了标准与 URL 安全两类字母表 |
| 相关格式 | PEM 文件、数据 URI、JWT 的载荷与签名、邮件附件 |
典型使用场景
- 在纯文本协议里传二进制:JSON 字段、HTTP 头、配置项中嵌入图片或密钥字节
- 邮件与附件:传统邮件传输只能承载文本,二进制内容需先编码
- 数据 URI:把小型图片直接内联到 HTML 或 CSS 中,减少请求数
- 令牌与签名:认证令牌的载荷与签名以 Base64 形式拼接传递
- 证书与密钥文件:PEM 格式就是 Base64 编码的二进制内容加上头尾标记
编解码示例
编解码示例
printf 'abc' | base64 # 输出 YWJj(恰好 3 字节,无填充)
printf 'a' | base64 # 输出 YQ==(补两个等号)
printf 'YWJj' | base64 -d # 解码回 abc
python -c "import base64; print(base64.b64encode(b'abc'))" # b'YWJj'
python -c "import base64; print(base64.b64decode('YQ=='))" # b'a'
echo -n 'admin:pass' | base64 # HTTP Basic 认证的凭据形式
base64 -w 0 file.bin > file.b64 # 单行输出,便于放进配置或 JSON长度对照
| 输入字节数 | 填充 | 输出字符数 |
|---|---|---|
| 1 | == | 4 |
| 2 | = | 4 |
| 3 | 无 | 4 |
| 4 | == | 8 |
| 5 | = | 8 |
| 6 | 无 | 8 |
| n | 余 1 补 2、余 2 补 1、余 0 不补 | 向上取整到 4 的倍数 |
Base64 常被误认为加密:它没有任何密钥,任何工具一条命令即可还原。把敏感数据「用 Base64 处理一下」再存放或传输,等于明文。需要保密时必须叠加真正的加密机制。
体积开销要提前算:Base64 之后大小约增加 33%,大文件内联到文本协议中会同时带来内存与带宽压力。超过一定体积的内容应走二进制通道,而不是编码后塞进文本字段。
PEM 与 DER 的关系容易混淆:DER 是二进制编码,PEM 是把它 Base64 化并加上头尾标记与换行的文本形式。工具通常能自动识别两者,但手工拼接文件时格式搞错会直接解析失败。