如何使用 Base36 转换器
- 在 输入 · 文本 中输入文本。它的 UTF-8 字节会被编码,结果显示在 输出 · Base36 中。
- 在输出下方的 大小写 中选择 小写 或 大写,两种的解码方式相同。
- 要转换数字,请把 从 设为 整数(大数),然后输入十进制值。如果改过 到,请把它设回 Base36。
- 要解码,请在方向切换中点击 Base36 → 文本;或者把 到 设为 整数(大数),得到十进制结果。
Base36 与十进制互转
Base36 先用 0–9 计数,然后是 a–z,所以 a 是 10,z 是 35。每一位的权重是它右边一位的 36 倍:
| Base36 | 十进制 | 说明 |
|---|---|---|
z | 35 | 最大的一位数 |
10 | 36 | |
zz | 1295 | 35 × 36 + 35 |
1000 | 46656 | 36³ |
21i3v9 | 123456789 | |
2gosa7pa2gv | 9007199254740991 | JavaScript 中的 Number.MAX_SAFE_INTEGER |
3w5e11264sgsf | 18446744073709551615 | 2^64 − 1 |
转换器使用 BigInt,所以 64 位和 128 位的值都能精确得出。它的上限是 64 KB 的输入,远超任何 ID 的长度。
Base36 用在哪里
Base36 适合那些需要简短、又必须经受住大小写变化的标识符:会被某些软件转成小写的 URL、不区分大小写的文件系统,以及需要念出来或照着纸面输入的代码。Reddit 的帖子和评论 ID 就是一个例子。大多数编程语言也能在不借助库的情况下读取 Base36 数字。
与其他方案相比,Base36 牺牲了一些紧凑性来换取不区分大小写。16 个随机字节用 Base36 是 24 或 25 个字符,用 Base62 是 21 或 22 个,用 hex 是 32 个。Base62 更短但区分大小写;Base32 同样不区分大小写,但它把字母表固定为 5 比特分组,还会加填充。
文本、字节与前导零
对于文本和其他字节,转换器把输入当作一个大端序的大数,再用 36 进制写出这个数。Hello 的字节是 48 65 6c 6c 6f,对应数字 310939249775,Base36 为 3yud78mn。前导零字节在纯数字中会消失,所以每个前导零字节都写成一个 0:字节 00 0a 编码为 0a。
整数 输入没有前导零的问题,因为十进制数没有可丢失的前导零字节。
在 JavaScript 和 Python 中使用 Base36
两种语言都原生支持数字转换:
(255).toString(36); // '73'
parseInt("73", 36); // 255
(2n ** 64n - 1n).toString(36) // '3w5e11264sgsf'
BigInt 可以按 36 进制输出,但没有对应的解析器,而 parseInt 超过 2^53 就会丢失精度。一个简短的循环就能解决:
function parseBase36(s) {
let n = 0n;
for (const ch of s.toLowerCase()) n = n * 36n + BigInt(parseInt(ch, 36));
return n;
}
parseBase36("3w5e11264sgsf"); // 18446744073709551615n
Python 的 int() 接受进制参数,任意大小都能处理:int("3w5e11264sgsf", 36) 返回 18446744073709551615。反方向没有内置函数,用字母表 0123456789abcdefghijklmnopqrstuvwxyz 写一个 divmod 循环即可。更多写法见 JavaScript 和 Python 页面。
常见问题
- 在值中间的
-、_或空格处报错。Base36 只有数字和字母。去掉分隔符;如果它们分隔的是多个 ID,就在分隔处拆开。 - 解码出的文本是乱码。这个字符串很可能是数字 ID,而不是编码后的文本。把 到 设为 整数(大数),把它当作数字查看。
- 在电子表格或 JSON 中最后几位出现细微差异。这个数字在某处经过了双精度浮点数。请让大 ID 从头到尾都以字符串形式保存。
常见问题
如何把 Base36 转换为十进制?
把 从 设为 Base36,到 设为 整数(大数),然后粘贴 Base36 值。zz 得到 1295,3w5e11264sgsf 得到 18446744073709551615,即最大的无符号 64 位数。
Base36 区分大小写吗?
不区分。大写和小写字母的值相同,所以 ZZ 和 zz 都是 1295。这让 Base36 成为能经受大小写变化的常见编码中最紧凑的一种。
为什么 JavaScript 的 parseInt 得出的数字不一样?
parseInt(s, 36) 返回双精度浮点数,只在 2^53 以内是精确的。parseInt("3w5e11264sgsf", 36) 返回 18446744073709552000,差了 385。请改为解析成 BigInt,写法见本页。
为什么 Hello 的 Base36 和 parseInt('Hello', 36) 不一样?
编码器把文本的五个字节转成一个数字,再用 36 进制写出来(3yud78mn)。而 parseInt 是把字母 H-e-l-l-o 当作 Base36 数字读取,得到 29234652。