Base32 是什么
Base32 是一种将二进制数据编码为可打印 ASCII 字符的方案,每 5 字节(40 位)数据编码为 8 个字符。与 Base64 相比,Base32 字符集更小(32 vs 64),编码后体积更大(约 60% 膨胀 vs 33%),但具有以下独特优势:
- 不区分大小写:适合口述、电话、手写场景
- 字符集仅含字母与数字:无
+///=等特殊符号,URL 友好 - 易被二维码、OCR 系统识别:纯字母数字的识别率高于含特殊符号的编码
- 无障碍友好:屏幕阅读器对字母数字的朗读更清晰
Base32 有两个主流变体:RFC 4648 标准与 Crockford Base32,两者在字符集、填充规则、校验机制上有显著差异。
RFC 4648 标准 Base32
RFC 4648 是 IETF 制定的 Base16/Base32/Base64 编码规范。标准 Base32 字符集为 A-Z(26 字母)与 2-7(6 数字),共 32 字符。选择 2-7 而非 0-9 是为了避开 0(与字母 O 易混)与 1(与字母 I/L 易混)。
编码原理
每 5 字节(40 位)数据拆分为 8 个 5 位段,每个 5 位段(0-31)映射到字符表:
字节: H e l l o
二进制:01001000 01100101 01101100 01101100 01101111
5位段: 01001 00001 10010 10110 11000 11011 00011 01111
字符: J B S W Y 3 D P
「Hello」编码结果为 JBSWY3DP。不足 5 字节的尾部用 = 填充至 8 字符的倍数。
填充规则
| 原始字节数 | 编码字符数 | 填充 = 数 | 总长度 |
|---|---|---|---|
| 1 | 2 | 6 | 8 |
| 2 | 4 | 4 | 8 |
| 3 | 5 | 3 | 8 |
| 4 | 7 | 1 | 8 |
| 5 | 8 | 0 | 8 |
应用场景
- TOTP 共享密钥:Google Authenticator、RFC 6238 TOTP 标准要求密钥以 Base32 编码
- DNS 主机名编码:DNS 协议中主机名不区分大小写,Base32 是天然适配
- P2P 协议握手:BitTorrent、磁力链接的 info hash 常用 Base32
- 二维码短链:纯字母数字的二维码编码效率更高
Crockford Base32
Douglas Crockford 设计的 Base32 变体,专为人工输入场景优化。核心设计理念是「让人类输入错误尽可能少」。
字符集差异
Crockford 字符集为 0-9(10 数字)与 A-Z 去除 I/L/O/U(22 字母),共 32 字符:
| 字符集 | 字符 | 排除原因 |
|---|---|---|
| RFC 4648 | ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 | 无(标准字符集) |
| Crockford | 0123456789ABCDEFGHJKMNPQRSTVWXYZ | I/L(与1混)、O(与0混)、U(意外脏话) |
易混字符归一化
Crockford 解码时自动归一化易混字符:
I/i/L/l→ 数字1O/o→ 数字0
这意味着用户输入 O0O0 与 0000 解码结果相同。这种容错设计让口述、手写场景的输入错误率大幅降低。
不使用填充
Crockford 规范不使用 = 填充。编码结果长度直接反映原始数据长度,更紧凑。
校验和机制
Crockford 规范支持在编码末尾附加 1 个校验字符,用于识别输入错误:
- 将原始字节序列视为大整数
- 计算
value mod 37(37 是大于 32 的最小质数) - 映射到字符表
0-9A-Z*~$=U(共 37 字符)
校验和可识别大部分单字符替换错误与部分换位错误。例如:
- 用户输入
91B7(正确)→ 校验通过 - 误输为
91B8(末位错)→ 校验失败,提示「数据可能被误输入」 - 误输为
19B7(换位)→ 校验失败(mod 37 对换位敏感)
校验和不能纠错,但能提示用户重新核对,避免静默错误。
RFC 4648 vs Crockford 对比
| 维度 | RFC 4648 | Crockford |
|---|---|---|
| 字符集 | A-Z + 2-7 | 0-9 + A-Z 去除 I/L/O/U |
| 大小写敏感 | 否(解码自动归一化) | 否(解码自动归一化) |
| 易混字符处理 | 无 | I/L→1, O→0 |
| 填充 | = 填充至 8 倍数 | 不填充 |
| 校验和 | 无 | 可选附加 1 字符(mod 37) |
| 主要场景 | 机器间传输(TOTP、DNS) | 人工输入(账号、密钥指纹) |
| 标准文档 | RFC 4648 | Crockford 个人规范 |
与 Base64 的选型决策
| 场景 | 推荐 | 理由 |
|---|---|---|
| JWT、Data URL、图片内联 | Base64 | 体积最小(33% 膨胀),机器处理 |
| TOTP 共享密钥 | Base32 | RFC 6238 标准要求 |
| 账号号码、订单号 | Crockford | 人工输入容错 + 校验和识别错误 |
| 二维码短链 | Base32 | 纯字母数字二维码效率更高 |
| DNS 编码 | Base32 | DNS 不区分大小写 |
| 屏幕阅读器朗读 | Base32 | 字母数字朗读清晰,符号易歧义 |
| OCR 自动识别 | Base32 | 纯字母数字识别率更高 |
JavaScript 实现要点
编码流程
function encodeBase32(bytes, alphabet, padding) {
let output = '';
let buffer = 0; // 累积位
let bits = 0; // 当前累积位数
for (const byte of bytes) {
buffer = (buffer << 8) | byte;
bits += 8;
while (bits >= 5) {
bits -= 5;
output += alphabet[(buffer >> bits) & 0x1f];
}
}
// 处理剩余不足 5 位的尾部
if (bits > 0) {
output += alphabet[(buffer << (5 - bits)) & 0x1f];
}
// RFC 4648 标准要求填充 = 至 8 的倍数
if (padding) {
while (output.length % 8 !== 0) output += '=';
}
return output;
}
Crockford 校验和实现
function crockfordChecksumChar(bytes) {
// 用大数取模算法避免精度问题
let mod = 0;
for (const byte of bytes) {
mod = (mod * 256 + byte) % 37;
}
return '0123456789ABCDEFGHJKMNPQRSTVWXYZ*~$=U'[mod];
}
注意:直接用 Number 计算 value mod 37 会因 Number.MAX_SAFE_INTEGER(2^53-1)限制丢失精度。逐字节累积取模可避免此问题。
解码时的易混字符归一化
function decodeCrockfordChar(ch) {
const table = buildCrockfordDecodeTable(); // 0-9A-Z + 归一化映射
const val = table[ch];
if (val === undefined) throw new Error(`非法字符 "${ch}"`);
return val;
}
// I/i/L/l → 1, O/o → 0 已在 table 中预置
真实应用场景
TOTP 共享密钥
Google Authenticator、Authy 等 TOTP 应用要求用户扫描二维码或手动输入 Base32 编码的共享密钥:
密钥(Base32):JBSWY3DPEHPK3PXP
密钥(Hex): 48656c6c6f48656c6c6f
手动输入时,用户通过「J-B-S-W-Y-3-D-P」逐字符输入,无需区分大小写。Base32 的字符集设计让口述(电话支持场景)也变得可行。
账号号码
银行账号、订单号、会员卡号等需要人工输入的标识符,Crockford Base32 + 校验和是理想选择:
- 去除 I/L/O/U 避免最常见混淆
- 校验和识别单字符输入错误
- 不区分大小写降低输入门槛
- 无
=填充更紧凑
密钥指纹
SSH 公钥指纹、PGP 密钥 ID 等场景,Crockford Base32 让用户在核对指纹时更不容易出错:
SSH 指纹(Base32):9KM8X1X5P3Q7Y2R6
^^^^^^^^^^^^^^^^^^^
用户核对时即使误输 I 当 1 也能正确识别
工具矩阵联动
本站的 Base32 编解码工具与以下工具形成「编码体系」闭环:
- Base32 编解码工具:RFC 4648 + Crockford 双变体 + 校验和
- Base64 编解码工具:标准 + URL 安全变体
- Base64 图片互转:图片与 Data URL 双向转换
- Hash 计算:SHA-1/256/512 摘要,输出 HEX 或 Base64
- JWT 解码:JWT 三段均为 Base64URL 编码
- JWE 解码:JWE 五段均为 Base64URL 编码
用户可:①Hash 工具计算摘要后用 Base32 工具编码为 Crockford 格式便于口述核对;②Base64 工具解码 JWT 后用 Base32 工具重新编码用于 DNS 场景;③Base64 图片工具生成 Data URL 后用 Base32 工具转换为二维码友好格式。
总结
Base32 不是 Base64 的替代品,而是互补品。RFC 4648 标准 Base32 适合机器间传输(TOTP、DNS),Crockford Base32 适合人工输入场景(账号、密钥指纹)。两者结合,覆盖了从机器处理到人工交互的全场景编码需求。
选择 Base32 还是 Base64 的核心决策点:数据是否需要人工输入或口述? 如果是,Base32(特别是 Crockford 变体)是更好的选择;如果纯机器处理且追求体积最小,Base64 仍是首选。