IP 地址怎么转成十进制?192.168.1.1 等于 3232235777 的换算与三个坑
IPv4 地址本质是一个 32 位整数,192.168.1.1 只是把这个整数按四个 8 位分段、用点隔开写出来。转成十进制只有一件事:四段分别乘 256 的幂,再相加。
十进制 = 第一段×16777216 + 第二段×65536 + 第三段×256 + 第四段
代入 192.168.1.1:192×16777216 + 168×65536 + 1×256 + 1 = 3232235777。
本文用IPv4 地址转换工具实测了 7 组输入,把五路输出各自能用在什么地方、哪些写法会被拒,以及「系统认、工具不认」的整数写法都记下来。

手算一遍:四段各占 8 位
192.168.1.1 拆开是 192、168、1、1 四个数,每个数占 8 个二进制位,取值范围 0–255。相邻两段之间差 256 倍,所以第一段的权重最大:
| 段位 | 权重 | 本段数值 | 乘积 |
|---|---|---|---|
| 第一段 | 16777216(256³) | 192 | 3221225472 |
| 第二段 | 65536(256²) | 168 | 11010048 |
| 第三段 | 256(256¹) | 1 | 256 |
| 第四段 | 1(256⁰) | 1 | 1 |
| 合计 | 3232235777 |
四段合起来正好 32 位,所以上限是 255.255.255.255 = 4294967295,也就是 2³²−1。实测输入 255.255.255.255,工具给出的十进制是 4294967295、十六进制 FFFFFFFF;下限 0.0.0.0 是 0。
这也解释了一个常见疑问:为什么 IP 越大、数字越大,但字符串排序会乱。 10.0.0.1 的数值比 9.0.0.1 大,按字符串排却排在前面(字符 1 小于 9)。
反向:3232235777 怎么还原成 192.168.1.1
一直除以 256、记余数,余数从后往前排就是四段:
3232235777 ÷ 256 = 12625921 余 1 → 第四段 1
12625921 ÷ 256 = 49320 余 1 → 第三段 1
49320 ÷ 256 = 192 余 168 → 第二段 168
192 ÷ 256 = 0 余 192 → 第一段 192
得到 192.168.1.1。程序里通常用位运算代替除法:取最高 8 位用 (n >>> 24) & 255,依次右移 16、8、0 位。注意 JavaScript 的位运算结果是 32 位有符号,处理 2147483647 以上的地址要先 n >>> 0 转成无符号,否则符号位会把结果变成负数。
五路输出分别是什么
| 输出行 | 192.168.1.1 的结果 | 用途与注意 |
|---|---|---|
| 十进制 | 3232235777 | 存库、做范围比较 |
| 十六进制 | C0A80101 | 每段两位、大写,不带 0x 前缀 |
| 二进制 | 11000000.10101000.00000001.00000001 | 每段 8 位,带点分段 |
| IPv6 映射 | 0000:0000:0000:0000:0000:ffff:c0a8:0101 | ::ffff:192.168.1.1 的完整写法 |
| IPv6 短格式 | ::ffff:c0a8:0101 | 同一地址的压缩写法 |
三个容易误读的地方:
1. 十六进制省略前导零。 输入 1.2.3.4,十六进制只显示 1020304(7 位),完整值应是 01020304;输入 0.0.0.0 只显示一个 0。不是丢了位,是前导零没补。

2. 二进制带点。 这是按四段输出的,直接粘进只认连续 32 位二进制的程序会报格式错,用前先去掉点。
3. IPv6 映射不是能访问的地址。 ::ffff:c0a8:0101 是 IPv4-mapped IPv6 的表示法,用来在 IPv6 的数据结构里标记「这其实是个 IPv4 地址」,它不是一条可以 ping 通的 IPv6 地址。想确认网站是否支持 IPv6,看的是域名的 AAAA 记录和实际拨测结果,不是看这一行——具体测法见IPv6 网站打不开怎么测?IPv6 网站测速、Ping、TCPing 三个工具分别测什么。
工具只认四段点分十进制
实测三类输入都会被拒,输入框下方出现红字「IPv4 地址格式不正确」,五行结果全部替换为「请输入合法的 IPv4 地址」:
3232235777:纯整数,没有点192.168.1.256:某一段超出 0–255010.1.1.1:带前导零

工具页写明所有转换在浏览器本地完成、不上传服务器。要做反向换算,只能自己按上面的除法算,或者交给系统的解析器——而系统的判断标准和这个工具并不一样。
系统认整数,工具不认:一个真实的不一致
在 Debian 13(glibc)上实测:
| 输入 | 系统解析结果 |
|---|---|
getent ahostsv4 3232235777 |
192.168.1.1 |
Node dns.lookup("3232235777") |
192.168.1.1 |
Node dns.lookup("010.1.1.1") |
8.1.1.1(前导零按八进制) |
getent ahostsv4 0x7f000001 |
127.0.0.1(十六进制写法) |
getent ahostsv4 127.1 |
127.0.0.1(省略段的写法) |
curl http://2130706433/ 的 Trying |
127.0.0.1:80 |
也就是说,同一串数字在「工具校验」和「系统解析」两边结论相反:工具判它格式错,系统的 getaddrinfo 却把它当合法 IPv4 处理。前导零按八进制解释这一点尤其容易踩:010 是 8,不是 10。
对做服务端的人,这直接影响 SSRF 防护。很多代码在字符串层面拦 127.0.0.1、localhost,但 http://2130706433/、http://0177.0.0.1/、http://0x7f000001/ 这类写法能被解析器接受。可靠的做法是先解析、拿到实际 IP 再比较,而不是在原始字符串上匹配黑名单。
存数据库为什么爱用整数
把 IP 存成整数有三个实在的好处:
- 排序正确。 数值大小和地址先后一致,字符串排序会乱(10.0.0.1 与 9.0.0.1)。
- 占位固定。 点分十进制最长 15 字节且变长,整数固定 4 字节,索引更小。
- 范围查询能走索引。 查一个网段就是
BETWEEN两个整数,不用做字符串前缀匹配。
有一个必须注意的边界:32 位有符号整型存不下 2147483647 以上的地址。 192.168.1.1 的 3232235777 按 32 位有符号表示是 -1062731519(3232235777 − 4294967296)。所以要存整数就选无符号:MySQL 用 INT UNSIGNED(上限正好 4294967295),或直接 BIGINT。MySQL 也自带 INET_ATON() / INET_NTOA() 做双向换算,不必自己写公式。
什么时候不用自己算
如果目的只是「这个 IP 是哪里的」,根本不需要转十进制,直接查归属地:IP 地址查询。查到的是机房所在地而不是使用者所在城市,属于正常现象,原因见IP 地址查询显示的位置不对?CDN 节点、AnyCast、IP 库差异与只到城市。
要做的是「网站从哪些地方能不能打开」,用拨测比转换地址更直接:从各地节点发起请求,看的是实际连通结果。
一句话收口:换算本身只有一条公式,容易出错的永远是格式——前导零、点分段、有符号溢出,以及系统解析器和校验器各认一套。
常见问题
192.168.1.1 转成十进制是多少?
3232235777。算法是 192×16777216 + 168×65536 + 1×256 + 1,四段分别乘 256 的三次、二次、一次、零次方再加起来。实测在 IPv4 地址转换器里输入 192.168.1.1,十进制一行显示 3232235777,十六进制 C0A80101。
为什么十六进制结果少几位?1.2.3.4 显示的是 1020304。
因为前导零被省略了,不是算错。1.2.3.4 的十进制是 16909060,十六进制完整应为 01020304,去掉开头的 0 就是 1020304;0.0.0.0 更极端,十六进制只显示一个 0。需要固定 8 位就把结果补到 8 位(padStart(8, "0"))。
二进制那一行为什么是带点的?
工具按四段分别输出 8 位,用点隔开,192.168.1.1 得到 11000000.10101000.00000001.00000001。这种写法和点分十进制一一对应,方便对照;但粘到只认连续 32 位的地方会报格式错,需要去掉点或改用位运算。
能不能输入十进制数字反查 IP?
这个工具不行,它只接受四段点分十进制。实测输入 3232235777,页面红字提示「IPv4 地址格式不正确」,五行结果全部变成「请输入合法的 IPv4 地址」。反查要自己算:一直除以 256 取余,3232235777 除四次得到 192、168、1、1。
为什么 010.1.1.1 工具说格式不对,系统却能解析?
工具要求每段是标准十进制,前导零直接拒。但 glibc 的解析器把前导零当八进制:本机实测 dns.lookup("010.1.1.1") 返回 8.1.1.1。同样,纯数字 3232235777 被解析成 192.168.1.1、2130706433 被解析成 127.0.0.1。拦 SSRF 时只在字符串上比对 127.0.0.1 是不够的。
数据库里 IP 该存整数还是字符串?
要排序、按网段查范围就存整数:字符串排序会把 10.0.0.1 排在 9.0.0.1 前面,整数没有这个问题,而且固定 4 字节、索引更小。注意用无符号:192.168.1.1 的 3232235777 按 32 位有符号存会变成 -1062731519,MySQL 要用 INT UNSIGNED(上限 4294967295)或 BIGINT,也可以直接用 INET_ATON()/INET_NTOA() 换算。