进制转换怎么用?二进制、十六进制与全角半角排查
读日志、调接口、排查密码验证失败时,问题往往落在两件小事上:进制没换算对,或者文本里混了全角字符。这两类问题的判断方法都很固定,能算清楚就不会再猜。
- 2 的幂次进制之间可以直接按位分组:二进制每 4 位对应 1 位十六进制,每 3 位对应 1 位八进制,不需要做除法
- 十六进制两位正好表示一个字节,所以 0xFF 是 255、0x10 是 16,前缀不同时同样的写法含义完全不同
- 全角数字的码位是 U+FF11,半角数字是 U+0031,两者不相等,用全角字符输入的密码必然验证失败
- 全角空格是 U+3000,不是普通空格 U+0020;它在不同语言里的 trim 行为不一致,是最难肉眼发现的一类脏字符
- 全角字母数字的码位固定比半角大 0xFEE0,全角 A 是 U+FF21,半角 A 是 U+0041
- 进制转换与全角半角转换都在浏览器本地完成,输入的内容不会上传到服务器
#二进制、八进制、十六进制分别在什么时候出现
十六进制用于表示字节,八进制在文件权限里最常见,二进制是位运算的基础 —— 三种进制各有固定场景,不是可以随便替换的写法。
同一个数值 255 在四种进制下的写法和典型用途:
| 进制 | 写法 | 典型场景 |
|---|---|---|
| 二进制 (2) | 0b11111111 | 位运算、权限位、协议标志 |
| 八进制 (8) | 0o377 | Linux 文件权限、chmod 755 |
| 十进制 (10) | 255 | 业务字段、日常数值 |
| 十六进制 (16) | 0xFF | 字节、内存地址、颜色值、哈希摘要 |
用 进制转换 输入一个数字并选好当前进制,四种进制的结果会实时同步显示,支持负数、小数和超出 2^53 的大整数。
容易被忽略的是前缀:0x 是十六进制、0b 是二进制、0o 是八进制。少了前缀,10 和 0x10 差 6 倍,这是换算里最常见的错误来源。
#进制之间怎么互转
2 的幂次进制之间可以直接按位分组,不需要做除法。 这是手算时最省事的一条规则,也是很多人算错的地方。
#二进制和十六进制:四位一组
一位十六进制正好等于四位二进制,所以从右往左每 4 位分一组,逐组查表即可:
二进制 1011 1111 0000 1101
分组 B F 0 D
结果 0xBF0D反向转换更简单:把每个十六进制字符展开成固定的 4 位二进制,不足 4 位前面补 0。
#二进制和八进制:三位一组
一位八进制等于三位二进制,分组宽度是 3 而不是 4:
二进制 111 101 010
分组 7 5 2
结果 0o752分组必须从右往左。从左往右分组时,位数不是 3 或 4 的整数倍就会错位,例如 1011 从左边按 3 位分成 101|1,得到的结果是错的。
#小数部分要单独换算
小数部分用「乘基取整」,方向与整数部分的「除基取余」相反,两部分要分别算完再拼起来。
0.625 × 2 = 1.25 取整数位 1
0.25 × 2 = 0.5 取整数位 0
0.5 × 2 = 1.0 取整数位 1
结果:0.101需要注意,0.1 这类十进制小数在二进制里是无限循环的,转换结果必然有精度损失 —— 这也是 0.1 + 0.2 在很多语言里不等于 0.3 的根源。
#全角字符为什么会把程序搞崩
全角字符和半角字符是两个不同的字符,计算机不认为它们等价,所以「看起来一样」的密码实际上并不一样。
- 全角数字
1的码位是 U+FF11,半角1是 U+0031 - 全角字母
A是 U+FF21,半角A是 U+0041 - 全角空格
是 U+3000,半角空格是 U+0020 - 全角下划线
_是 U+FF3F,半角_是 U+005F
它们在屏幕上可能只差一点宽度,但在字符串比较、哈希计算、数据库唯一索引里完全是两个值。用户看到的是「密码明明是对的」,程序看到的却是「字符串不匹配」。
中文输入法在中文标点模式下会把数字、字母和下划线一并打成全角。 这是密码验证失败最常见的原因,而且校验逻辑不会报「格式错误」,只会报「用户名或密码不正确」,让人一直往错误的方向排查。
#怎么快速定位混入的全角字符
先看字符数与字节数,再逐个字符比对码位 —— 顺序反了会很浪费时间。
| 现象 | 原因 | 用什么查 |
|---|---|---|
| 密码验证失败,但肉眼看着一模一样 | 数字或字母是全角 | 全角半角转换 |
| 表单提示「含有非法字符」 | 混入全角空格 U+3000 | 文本统计 看字节数 |
JSON 里出现 \uff11 这类转义 | 全角字符被序列化 | Unicode 中文互转 |
| 重复数据插不进唯一索引 | 全角与半角被当成两条记录 | 全角半角转换 |
具体定位步骤:
- 复制出问题的字符串,先看字符数与字节数是否和预期一致
- 拿一个确认正确的字符串做对比,找出多出来或不一样的字符
- 用 全角半角转换 转成半角后重新比对
- 确认修复后再更新数据库或密码,不要反过来去改验证逻辑
全角半角转换会自动保留汉字与中文标点(。、,),只转换字母、数字、标点与空格。所以转换整段中文文本是安全的,不会把「。」变成「.」。
#全角半角转换的其它用途
除了修密码,全角半角转换主要用于数据清洗与文本规范化。
常见场景有三个:
- 从 Excel、PDF、聊天记录里复制出来的文本,数字和括号常常是全角
- 中文排版规范要求数字与字母用半角,但句读标点用全角
- 搜索接口要做输入规范化,否则「ABC」和「ABC」搜不到同一批结果
需要注意长度变化:一个全角字符占 3 个 UTF-8 字节,转成半角后只占 1 个。如果目标字段有长度限制,转换后要重新校验一次。
全角半角转换只改变字符码位,不做繁简转换,也不做大小写转换。需要统一大小写属于另一个处理环节。
#什么时候该用哪个工具
| 你想做的事 | 用哪个 | 说明 |
|---|---|---|
| 2/8/10/16 进制互转 | 进制转换 | 输入一个值,四种进制同步显示 |
| 把全角字母数字转成半角 | 全角半角转换 | 汉字与中文标点保持不变 |
| 看字符串有多少字符、多少字节 | 文本统计 | 两者不一致就能发现隐藏字符 |
把中文转成 \uXXXX 转义 | Unicode 中文互转 | 排查编码类问题时用 |
| 把字节流转成可读文本 | Base64 编码解码 | 进制转换只处理数值,不处理字节流 |
| 核对文件是否被改动 | SHA 系列哈希 | 十六进制摘要的典型用途 |
#常见问题
#为什么密码明明输对了却提示错误?
先怀疑全角字符。中文输入法在中文标点状态下输入的字母、数字和下划线都是全角,码位与半角不同,字符串比较必然失败。把密码粘进 全角半角转换 转成半角再试一次,就能立刻验证这个猜测。
#0x10 到底是 10 还是 16?
是 16。0x 前缀表示十六进制,0x10 = 1×16 + 0 = 16。同理 0b10 是二进制的 2,0o10 是八进制的 8。前缀不同时,同样的数字写法含义完全不同,这是进制换算里最容易犯的错。
#二进制、八进制、十六进制分别有什么实际用途?
十六进制用来紧凑表示字节与二进制数据,两个字符对应一个字节,所以哈希摘要和内存地址都用它;八进制主要出现在 Linux 文件权限(chmod 755)与部分转义写法里;二进制是底层表示,用于位运算和标志位。十进制只是给人看的,计算机内部一律是二进制。
#全角空格为什么特别难排查?
因为它是 U+3000 而不是 U+0020,视觉上只是「稍微空了一点」,复制粘贴时几乎分辨不出。更麻烦的是各语言处理不一致:JavaScript 的 trim() 和 Python 的 strip() 会去掉它,Java 的 String.trim() 只处理 U+0020 及以下、去不掉。同一份数据在不同语言里表现不同,用 文本统计 看字节数就能确认。
#进制转换支持小数和超大整数吗?
支持。整数部分用 BigInt 精确计算,不会出现超过 2^53 之后精度丢失的问题;小数部分按 IEEE 754 二进制浮点表示,像 0.1 这种无法用有限二进制位表示的小数会有精度损失;负数会保留符号。如果对精度敏感,建议改用十进制字符串传输。