Base32 编码/解码
RFC 4648 Base32 编码,谷歌验证器密钥常用
Base32:为什么 TOTP 验证码用的是它而不是 Base64
Base32 与 Base64 的关系
两者都是把二进制映射成可打印字符,区别在字母表大小和每字符携带的位数:
| Base64 | Base32 | |
|---|---|---|
| 字母表 | 64 个:A-Z a-z 0-9 + / | 32 个:A-Z 2-7 |
| 每字符位数 | 6 位 | 5 位 |
| 体积开销 | 约 33% | 约 60% |
| 大小写敏感 | 是 | 否 |
| 易混淆字符 | 有(0/O、1/l/I) | 无(数字只用 2-7) |
Base32 明显更浪费空间——同样数据比 Base64 长 20% 以上。它换来的是大小写不敏感、没有易混字符、可以放心手抄和口头转述。当编码结果要被人手输入时,这个取舍是值得的。
为什么 TOTP 用的是 Base32
两步验证(Google Authenticator、Authy 这类)的共享密钥按规定用 Base32 编码(RFC 4648 / RFC 6238)。原因就是上面那条:密钥经常需要人工录入或抄写,大小写不敏感、不含 0 和 1 这两个最容易与字母混淆的字符,能显著降低抄错的概率。
看到一串全大写、只有 A-Z 和 2-7 的字符串(常见长度 16、26、32 字符),基本可以确定是 Base32,而不是某种加密结果——它本身不含任何保密性,安全来自 TOTP 算法和密钥的随机性。
填充规则
Base32 每 5 字节(40 位)编成 8 个字符。不足 5 字节时用 = 补齐:
| 输入字节 | 输出字符 | 填充 |
|---|---|---|
| 1 | 2 | ====== |
| 2 | 4 | ==== |
| 3 | 5 | === |
| 4 | 7 | = |
| 5 | 8 | 无 |
TOTP 密钥通常省略填充,解码时按长度自行补回。也有 crockford 变体把字母表换成 0-9 A-Z(去掉 I L O U),用于需要更强抗误读能力的场合。
工具支持标准 Base32 与 Base32hex,编码解码双向,全部在浏览器本地完成。
常见问题
Base32 和 Base64 有什么区别?
Base32 只使用大写字母和数字 2-7,不含容易混淆的 0 O 1 I,体积大 60%,适合人工抄写场景(如验证器密钥)。