进制转换
2/8/10/16 及任意 2-36 进制互转,支持大数,二进制分组显示。
进制转换:十六进制、位与字节的对应关系
进制的本质是位值记数法
同样的数值,在不同进制下写成不同形状。255 在二进制里是 11111111,八进制里是 377,十六进制里是 FF。它们表示的是同一个数,只是"每位的权重"不同(分别是 2 的幂、8 的幂、16 的幂)。
所以进制转换不改变数值,只改变写法。这和"255 与 0xFF"是同一个数的关系一样。
为什么程序员用十六进制
关键在于一个十六进制位恰好对应 4 个二进制位(因为 16 = 2⁴),而一个字节是 8 位,于是一个字节就是两个十六进制位。这个整齐的对应让读写变得极为方便:
| 二进制 | 十六进制 | 十进制 | 说明 |
|---|---|---|---|
1010 | A | 10 | 4 位 = 1 个十六进制位 |
11111111 | FF | 255 | 1 个字节 = 2 个十六进制位 |
1010 1010 | AA | 170 | 分组后可肉眼核对每一位 |
如果用十进制表示同样的字节,就无法一眼看出位模式。这也是内存地址、颜色值(#FF5733)、哈希值、字符编码、网络包分析、权限掩码全部用十六进制的原因。
本工具在输出二进制时会每 4 位加空格分组,正是为了配合这个对应关系——分组后一组就是一位十六进制,人工核对非常方便。
进制与位宽的实用对照
| 位宽 | 取值范围(无符号) | 取值范围(有符号,补码) |
|---|---|---|
| 8 位 | 0 – 255(0xFF) | −128 – 127 |
| 16 位 | 0 – 65535(0xFFFF) | −32768 – 32767 |
| 32 位 | 0 – 4294967295(0xFFFFFFFF) | −2147483648 – 2147483647 |
| 64 位 | 最大约 1.8 × 1019 | 约 ±9.2 × 1018 |
看到 0xFF 应该立刻联想到 255(一个字节全满),看到 0xFFFFFFFF 联想到 32 位全满——这是读代码和看日志时的基本直觉。
这里有一个重要的概念:同一串二进制位,按有符号和无符号解释得到不同的数。例如 0xFF:无符号是 255,有符号补码是 −1。所以"看到 FF 就说它等于 255"在涉及有符号类型时是错的。负数用补码表示意味着最高位为 1 时按负数解释,这是溢出的常见来源。
为什么需要 BigInt
JavaScript 的数字是 IEEE 754 双精度浮点,能精确表示的整数上限是 253 − 1 = 9007199254740991。超过这个范围,整数运算会丢精度——这对进制转换是致命的,因为大数、加密相关的数值(哈希、密钥、区块链地址)经常远超这个范围。
本工具使用 BigInt 实现,不受 253 限制,只要内存允许就能处理任意长度的整数。所以可以安全地转换 64 位、128 位甚至更长的整数,不会出现末几位变成 0 或变成奇怪数字的情况。
常见错误
- 输入里的字符不属于该进制。在二进制下输入
2、在十六进制下输入G都是非法的。工具会直接报错并指出位置,而不是默默截断。 - 前缀被当成数值的一部分。
0x(十六进制)、0b(二进制)、0o(八进制)是编程语言里的字面量前缀,不是数值本身。转成十进制时要去掉前缀,否则0x里的x会被判为非法字符。 - 八进制在弱类型语言里的陷阱。JavaScript 历史上把以
0开头的数字当作八进制,所以0777曾等于 511 而不是 777。这个行为在严格模式下已废弃,但老代码里仍能见到,也是"数字莫名变值"的一个历史来源。 - 进制上限是 36。因为可用字符是 0-9 加 A-Z,共 36 个。base32、base64 这类编码不是进制——它们是位分组的编码方式(base64 用 64 个字符表示 6 位一组),名称里的数字含义不同。
- 负数需要约定。纯进制转换通常只针对非负整数。负数的表示方式(符号位、补码、偏移码)属于数据表示,不是进制问题,转换前必须明确约定。
工具怎么用
- 在数值框输入数字(如
1010或FF)。 - 选原进制与目标进制,支持 2 到 36 之间的任意进制。
- 点转换。二进制结果会按每 4 位分组,便于与十六进制对照。
适合做位掩码验证(把十六进制掩码转成二进制,一条条数哪几位是 1)、颜色值转换、权限值解读、以及校验收到的十六进制数据。全部在浏览器本地完成。
常见问题
支持多大范围的数?
使用 BigInt 实现,只要内存允许就能处理任意长度整数,不受 2^53 限制。
二进制为什么分组显示?
二进制位数很长,按每 4 位(半字节)加空格分组,便于阅读和人工核对。