十六进制转 IP
把 8 位十六进制值转换为点分十进制 IPv4 地址。0x 前缀可写可不写,点号、冒号、空格等分隔符都会被忽略。
手工推算一个十六进制地址
十六进制形式的 IPv4 地址,就是用八位十六进制数字表示的四个字节。每两位数字是一个字节,所以整个转换就是四次独立的"两位 16 进制转 10 进制"。字节顺序与点分记法一致,不需要做任何反转。
C0 -> C = 12,所以 12 × 16 + 0 = 192
A8 -> A = 10,所以 10 × 16 + 8 = 168
01 -> 0 = 0,所以 0 × 16 + 1 = 1
01 -> 0 = 0,所以 0 × 16 + 1 = 1
-----
192.168.1.1示例:0xAC100001
去掉前缀得到 AC100001,拆成 AC、10、00、01。AC 是 10 × 16 + 12 = 172。10 是 1 × 16 + 0 = 16。00 是 0。01 是 1。
结果:172.16.0.1
它落在 RFC 1918 的 172.16.0.0/12 范围内,是私有地址 —— 也就是从 AC100000 开始的同一个地址块。
读懂十六进制形式的掩码
掩码也常用十六进制书写,因为掩码本身是一个机器字,十六进制能让位模式看得见。FF 是全 1,00 是全 0,边界就落在第一个不是 FF 的字节上。
| 十六进制掩码 | 点分十进制 | 前缀 | 主机位 |
|---|---|---|---|
| FFFFFF00 | 255.255.255.0 | /24 | 8 |
| FFFFFF80 | 255.255.255.128 | /25 | 7 |
| FFFFFFC0 | 255.255.255.192 | /26 | 6 |
| FFFFFFE0 | 255.255.255.224 | /27 | 5 |
| FFFFFFF0 | 255.255.255.240 | /28 | 4 |
| FFFFFFF8 | 255.255.255.248 | /29 | 3 |
| FFFFFFFC | 255.255.255.252 | /30 | 2 |
| FFFFFFFE | 255.255.255.254 | /31 | 1 |
| FFFFFFFF | 255.255.255.255 | /32 | 0 |
| FFFF0000 | 255.255.0.0 | /16 | 16 |
| FF000000 | 255.0.0.0 | /8 | 24 |
数末尾的 0 位就等于数主机位。FFFFFF00 有八个 0 位,所以是 /24;在 32 位机器字里即使前面不补零,FFFFFF00 依然是 /24,因为前面的位隐含为 1,一直补到第 32 位。
常见错误
- 忘了 A-F 表示 10-15。把 A 当成 1,或者把 10 放在错误的位置,结果会偏得很远。A8 是 168,不是 108。
- 在右侧补零。短值缺的是前导零。AC10 补成 0000AC10 是 0.0.172.16,而不是 172.16.0.0。
- 不必要地反转字节序。标准的文本十六进制形式本身就是网络字节序。只有确认来源是小端时才需要反转。
- 把掩码当成完整地址来换算。像 FFFFFF00 这样的值是掩码而不是地址,按地址换算会得到 255.255.255.0 —— 形式上像个合法地址,但几乎肯定不是原本想要的。
参考:十六进制数字与十进制对照
| 十六进制 | 十进制 | 二进制 | 说明 |
|---|---|---|---|
| 0 | 0 | 0000 | 四位全为 0 |
| 1 | 1 | 0001 | 最低位为 1 |
| 7 | 7 | 0111 | A 类地址范围内最大的单数字十六进制值 |
| 8 | 8 | 1000 | 半字节的最高位为 1 |
| A | 10 | 1010 | 第一个字母;十进制为 10 |
| C | 12 | 1100 | 192 到 223 地址的首位数字 |
| E | 14 | 1110 | 224 到 239 地址的首位数字 |
| F | 15 | 1111 | 四位全为 1;两个 F 就是 255 |
常见问题
如何把十六进制转成 IP 地址?
把八位十六进制数字拆成四对,逐对转成十进制,再用点号连接。以 C0A80101 为例:C0 = 192,A8 = 168,01 = 1,01 = 1,得到 192.168.1.1。
怎么把一对十六进制数字转成十进制?
第一位乘以 16 再加上第二位。A8 中 A 是 10,10 × 16 = 160,加 8 得 168。C0 中 C 是 12,12 × 16 = 192,加 0 得 192。记住 A 到 F 分别代表 10 到 15。
十六进制值不足八位怎么办?
在左侧补零。像 AC10 这样的四位值只有 16 位,并不是一个完整的 IPv4 地址 —— 补成 0000AC10 后是 0.0.172.16,或者把它当成需要结合上下文才能确定的部分值。任何完整的 IPv4 地址都恰好是八位十六进制数字。
0x 前缀有影响吗?
对数值本身没有影响。转换器在解析前会去掉开头的 0x 或 0X,所以 0xC0A80101 与 C0A80101 都会得到 192.168.1.1。这个前缀的存在只是为了告诉编程语言该字面量是 16 进制。
可以直接粘贴 Wireshark 风格的十六进制转储吗?
如果只粘贴地址部分、用空格、点号或冒号分隔,这些分隔符都会被去掉。但包含其它字段的完整数据包转储不能用,因为工具期望的正是 32 位地址数据,它无法判断转储里哪几个字节才是地址。
为什么我的十六进制值看起来是反的?
网络协议以 big-endian(最高字节在前)保存多字节字段,这与点分十进制的顺序一致。如果你的值看起来是反的,很可能你看到的是调试器或内存转储中的 little-endian 表示,转换前需要先把四个字节反转过来。