Base32 编码工具

按 RFC 4648 的字母表把文本编成 Base32:每 5 bit 一组,四十 bit 是八与五的最小公倍数,所以五字节一组、输出八个字符,不足的部分用等号补到八的倍数。结果下面给出逐组 5 bit 明细与填充数量,也可以一键去掉填充。

字母表 ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 共 32 个字符,不含 0、O、1、I、L。
Hello → JBSWY3DP 字节数 5 → 字符数 8(填充 0 个,有效字符 8,膨胀 60.0%) -- 逐 5 bit 分组明细(Hello)-- 01001 = 9 → J 00001 = 1 → B 10010 = 18 → S 10110 = 22 → W 11000 = 24 → Y 11011 = 27 → 3 00011 = 3 → D 01111 = 15 → P -- 批量 -- Hello → JBSWY3DP hello → NBSWY3DP A → IE====== AB → IFBA==== ABC → IFBEG=== ABCD → IFBEGRA= ABCDE → IFBEGRCF Base32 → IJQXGZJTGI====== 你好 → 4S62BZNFXU====== a → ME======

默认示例:Hello 编成 JBSWY3DP。单行框、批量框、分组上限、填充开关任意一项改动即重新编码,单行框里按回车同样触发一次。

使用方法

  1. 「单行原文」默认填 Hello,光标停在这个框里直接按回车就编码一次,改动内容也会立刻重算,不必点按钮。
  2. 「明细分组上限」默认 16,范围 1 到 40。它只决定逐组 5 bit 明细显示多少组,不改编码结果;输入很长的文本时把它调小可以少看几屏。
  3. 「去掉填充」默认不勾选。勾选后输出里的等号会被删掉,串变短但不是标准 RFC 4648 形式,解码方要自己补回八的倍数。
  4. 「批量编码」默认写好十行示例,每行一条,按 Ctrl+Enter(Mac 上是 Cmd+Enter)一次算完;万一被清空,点编码时会自动填回这十行。
  5. 结果区第一行是「原文 → 编码串」,第二行给出字节数、字符数、填充数与膨胀率,下面跟着逐组 5 bit 明细,最后是批量结果逐行列出。
  6. 结果下面是一张 12 行的长度对照,把 1 到 12 字节分别折成输出字符数、填充数与膨胀率,默认显示 6 行,点「加载更多」展开全部,点「导出 CSV」存成带字节序标记的表格。
  7. 「复制结果」复制整段结论;「复制对照表」复制正文那张 12 行长度对照表;「重置」把单行框、批量框与开关恢复成默认值。
  8. 原文为空、批量里出现空行以外的非法情况,或分组上限不在 1 到 40 之间,都会给出针对该情况的具体提示,不会拿上一次的结果冒充本次输出。

这个 Base32 编码工具能解决什么问题

第一类场合是通道只吃大小写不敏感的字母数字。QR 码的 alphanumeric 模式、DNS 的 NSEC3 记录、某些文件系统的文件名,都不区分大小写或不允许特殊符号。Base64 区分大小写,放进这些场合会被改写;Base32 的字母表只有大写字母加数字 2 到 7,天然安全。

第二类场合是需要人手抄写或口述的串。双因素认证的密钥、设备配对码、订单核验码常常要在电话里念一遍,Base32 的字母表里没有 0、O、1、I、L、U,念错与抄错的概率显著低于混着数字与字母的串。

第三类场合是直接放进 URL 或文件名。Base64 字母表里的加号与斜杠在 URL 里要转义成减号与下划线,也就是 base64url 变体;Base32 的标准字母表里没有这两个字符,不需要额外变体,唯一要处理的只有作为填充的等号。

第四类场合是核对别人给的编码结果。同一段内容交给不同语言的标准库,填充、换行、大小写可能都不一样,但有效字符应当逐字相同。本页把逐组 5 bit 明细列出来,可以直接对着位串核对哪一组算错了。

本页做的是 RFC 4648 定义的 Base32编码,字母表为 ABCDEFGHIJKLMNOPQRSTUVWXYZ234567,与 Crockford、z-base-32 这些变体不是同一套。

计算原理与变量说明

编码分三步。第一步把文本按 UTF-8 折成字节序列;第二步把字节序列看成一条连续的位流,从左往右每 5 bit 取一组,每组的值 0 到 31 查字母表得一个字符;第三步把字符数补到 8 的倍数,缺几位就补几个等号。

输入 Hello:五个字节是 48 65 6C 6C 6F,写成二进制连起来是 01001000 01100101 01101100 01101100 01101111,共 40 bit。每 5 bit 一组正好分成八组:01001、00001、10010、10110、11000、11011、00011、01111,对应十进制 9、1、18、22、24、27、3、15,查字母表得 J、B、S、W、Y、3、D、P,拼起来就是 JBSWY3DP,不需要填充。

为什么取 5 bit。一个可打印字符要能放进 ASCII printable 区间,2 的 5 次幂是 32,正好凑出 32 个不含特殊符号的字符;取 6 bit 就是 Base64,字母表里不得不塞进加号与斜杠。5 这个数是「字母表干净」与「编码效率」之间的折中。

为什么是五字节一组。一个字节 8 bit,一组 5 bit,8 与 5 的最小公倍数是 40 bit,也就是 5 字节正好整除成 8 组。字节数不是 5 的倍数时,最后一组不满 5 bit,就在右边补零凑满,再用等号把总长度补到 8 的倍数。所以长度只会出现 8、16、24 这些八的倍数。

填充只补到八的倍数,不补到五字节。输入 1 字节共 8 bit,取两组还剩 3 bit,补两个零成第 2 组,有效字符 2 个,总长度补到 8,需要 6 个等号,结果形如 IE======。填充数量由总位数决定:1、2、3、4、5 字节分别补 6、4、3、1、0 个等号。

字母表的构成有讲究。A 到 Z 共 26 个字母,加数字 2 到 7 共 6 个,凑成 32 个。数字从 2 开始而不是从 0 开始,是为了避开 0 与 O、1 与 I、以及 L 的混淆:0 与 1 不进表,天然也就不会与 O 和 I 混。值 26 到 31 对应字符 2 到 7。

UTF-8 是字节层面的前提。中文与 emoji 在 UTF-8 里占 3 到 4 字节,编码时按字节而不是按字符切分。你好 是两个字符却是 6 字节,所以输出 4S62BZNFXU======,共 10 个有效字符加 6 个等号。

去掉填充要双方约定。等号只是把长度补齐到八的倍数,解码时可以先算再补。RFC 4648 要求保留填充,但很多实现(例如 TOTP 密钥的显示)会去掉。去掉之后串不再是标准形式,解码方必须知道该补几个等号。

完整示例

默认示例是 Hello。五个字节 48 65 6C 6C 6F,40 bit 整除成八组,结果 JBSWY3DP,填充 0 个,膨胀 60.0%。

把小写 hello 编一次:字节是 68 65 6C 6C 6F,首字节变了,第一组从 01001 变成 01101,结果 NBSWY3DP。大小写在这个编码里不是无关紧要的装饰,它改变字节值,也就改变整个串。

一到五字节的填充变化:A 编成 IE======(补 6 个),AB 编成 IFBA====(补 4 个),ABC 编成 IFBEG===(补 3 个),ABCD 编成 IFBEGRA=(补 1 个),ABCDE 编成 IFBEGRCF(不补)。五字节这一行是唯一没有等号的短串。

六字节的情况:Base32 这个词本身是 6 字节,48 bit 需要 10 个有效字符,总长度补到 16,补 6 个等号,结果 IJQXGZJTGI======。

非 ASCII 的情况:你好 在 UTF-8 里是 E4 BD A0 E5 A5 BD 共 6 字节,编成 4S62BZNFXU======。单字符 a 编成 ME======,注意它与 A 的 IE====== 完全不同。

勾选「去掉填充」后,上面所有串末尾的等号都会消失:IE====== 变成 IE,IFBEGRA= 变成 IFBEGRA,IJQXGZJTGI====== 变成 IJQXGZJTGI,而 JBSWY3DP 与 IFBEGRCF 本来就没有等号,保持不变。

Base32 长度与编码对照表

下表把 1 到 12 字节的输入折成输出长度,填充数由总位数决定,膨胀率 =(输出字符数 − 字节数)÷ 字节数。

输入字节输出字符填充等号有效字符膨胀率
1862700.0%
2844300.0%
3835166.7%
4817100.0%
580860.0%
616610166.7%
716412128.6%
816313100.0%
91611577.8%
101601660.0%
1124618118.2%
1224420100.0%

第二张表把三种常见 base 编码按八个维度摆在一起,用来判断该选哪一个。

维度Base16(Hex)Base32Base64
每字符承载4 bit5 bit6 bit
每字节产出2.0000 字符1.6000 字符1.3333 字符
编码效率50.0%62.5%75.0%
字母表大小163264
大小写敏感不敏感不敏感敏感
URL 与文件名安全安全(只有等号要处理)需要 base64url 变体
填充规则无填充等号补到 8 的倍数等号补到 4 的倍数
同内容相对长度150.0%120.0%100.0%

第三张表是选择依据:什么情况下 Base32 比 Base64 更合适,代价是什么。

序场景与理由
1大小写不敏感的场合(QR 码 alphanumeric 模式、文件名、DNS NSEC3)—— Base64 区分大小写
2需要手抄或口述的验证码—— 字母表不含 0、O、1、I、L、U
3要直接放进 URL 或文件名—— 不含加号与斜杠之外的特殊字符
4Base64 的加号与斜杠在 URL 里要改成减号与下划线,Base32 不需要变体
5代价:同样内容 Base32 比 Base64 长 20.0%
6RFC 4648 另外定义了 base32hex 变体(字母表 0-9A-V),用于需要按位序排序的场合
7Crockford Base32 额外去掉 I、L、O、U,并把解码时的 I 与 l 视为 1、O 视为 0
8z-base-32 重排字母表,把人类易读的字符排在前面,适合口头传递

读第一张表看周期:每 5 字节一个周期,输出稳定增加 8 个字符,膨胀率在 60.0% 到 700.0% 之间摆动,短输入最吃亏。读第二张表看取舍:效率是 50.0%、62.5%、75.0% 三档,换来的是大小写不敏感与 URL 安全。

结果边界、舍入与适用说明

常见问题

为什么要每 5 bit 一组,而不是 4 或 6?

4 bit 一组只有 16 个字符,效率低到 50.0%;6 bit 一组有 64 个字符,字母表里必须塞进加号与斜杠,还要区分大小写。5 bit 一组凑出 32 个字符,正好装下 26 个字母加 6 个数字,既避开了特殊符号,也避开了 0、O、1、I 这类易混形状。

为什么总长度一定是 8 的倍数?

因为 8 bit 与 5 bit 的最小公倍数是 40 bit,也就是 5 字节正好分成 8 组。字节数不是 5 的倍数时,最后一组补零凑满,再用等号把字符数补到 8 的倍数,于是只会出现 8、16、24 这些长度。

填充的等号数量为什么是 6、4、3、1、0 这种不规则序列?

填充数 = 8 − 有效字符数,而有效字符数 = 总位数除以 5 向上取整。1 字节 8 bit 得 2 个字符补 6 个,2 字节 16 bit 得 4 个补 4 个,3 字节 24 bit 得 5 个补 3 个,4 字节 32 bit 得 7 个补 1 个,5 字节 40 bit 得 8 个不补。

Base32 比 Base64 长多少?值得吗?

同样内容长 20.0%:每字节产出 1.6000 个字符对 1.3333 个字符,比值 1.2。是否值得看场景——需要大小写不敏感、手抄、进 URL 或文件名时这 20% 换来的兼容性是划算的,纯机器之间传大块二进制则 Base64 更合适。

字母表里为什么没有数字 0 和 1?

为了避开与字母 O、I、L 的混淆。26 个字母加 6 个数字才凑够 32 个,数字取 2 到 7 而不是 0 到 5,正是把 0 和 1 让出去的结果。手抄或口述的串尤其吃这个设计。

去掉填充后还能解码吗?

能,但解码方要自己算:把串长度补到 8 的倍数需要几个等号,是可以从长度推出来的。RFC 4648 要求保留填充,很多库也默认要求;去掉填充通常是出于显示或长度限制,双方要提前约定。

这个工具免费吗?

免费,无需注册即可使用。

输入的数据安全吗?

安全。编码在当前浏览器本地完成,不会上传输入内容。

相关工具