跳到主要内容

IP 转十进制 / IP 转整数:把 192.168.1.1 变成一个长整数

把 IPv4 点分地址换算成一个 32 位整数:原理是四段各 8 位拼成 32 位,用途包括数据库省空间存储、IP 范围比较和 geoip 查询,还能反转回点分地址。

发布于 作者 李雷
#网络 #IP #进制转换 #数据库

IP 转十进制:把一个 IPv4 地址压成单个长整数

我第一次真正用到 IP 转十进制,是在给一张登录日志表建索引的时候。原来那列是 15 个字符的 VARCHAR,存着 192.168.1.1 这样的字符串,一旦要查"某个子网里的全部访问",SQL 就得做一串字符串前缀匹配,慢得让人想砸键盘。后来把每个地址换算成一个整数,存进 BIGINT 列,范围查询直接变成一句 BETWEEN,索引体积也小了一截。那一刻我才明白,IP 转整数不是炫技,是实打实省钱省时间的基础操作。

一个 IPv4 地址到底是什么

点分十进制 192.168.1.1 只是给人看的写法。机器眼里,它是一串 32 位的二进制。四段数字,每段叫一个 octet,正好占 8 位,也就是一个字节,取值范围 0 到 255。四个字节首尾相连,拼成一个 32 位的整数,范围从 0 一直到 4294967295(也就是 255.255.255.255)。

所以"IP 转十进制"做的事很简单:把这四个字节当成一个大端排列的数,算出它对应的那个长整数。

拼接原理:四段各乘 256 的幂相加

关键在于每一段在 32 位里的权重不一样。第一段是最高有效字节,往后每段权重缩小 256 倍。换算公式就是把四段分别乘以 256 的幂再相加:

  • 第一段 × 256³,也就是 × 16777216
  • 第二段 × 256²,也就是 × 65536
  • 第三段 × 256¹,也就是 × 256
  • 第四段 × 256⁰,也就是 × 1

拿 192.168.1.1 套进去算一遍:

192 × 16777216 = 3221225472 168 × 65536 = 11010048 1 × 256 = 256 1 × 1 = 1

四项相加:3221225472 + 11010048 + 256 + 1 = 3232235777

所以 192.168.1.1 = 3232235777。这就是这个地址的十进制整数形态,一个数字就把四段信息全装下了。你可以在 IP 转十进制工具 里直接填进去对一遍,结果旁边还会并排给出二进制 11000000.10101000.00000001.00000001 和十六进制 0xC0A80101。

为什么要把 IP 存成整数

一个 32 位整数列,比 15 个字符的字符串小得多,建索引也快得多。但真正的好处在范围查询。

一整个子网,对应的就是一段连续的整数。比如 10.0.0.0/8 这个网段,网络地址 10.0.0.0 换算成整数是 167772160,广播地址 10.255.255.255 是 184549375。要统计这个网段的全部访问,SQL 写成 WHERE ip BETWEEN 167772160 AND 184549375 就行,干净利落,不用把 CIDR 运算塞进语句里。

geoip 库也是这么干的。那些把 IP 段映射到国家、城市的数据表,几乎都用整数区间做主键。查一个访客的归属地,本质就是拿他的 IP 整数去匹配落在哪个区间里,整数比较远比字符串比较快。限流器、防火墙规则,背后是同一套逻辑。换算成整数存一次,只在需要给人看的时候再转回点分写法。

反转:从整数还原回点分地址

整数转回 IP,就是把上面的拼接反过来做:把 32 位整数从高位到低位拆成四个字节。

拿 3232235777 来拆:先除以 16777216 取整得到 192,余下部分除以 65536 取整得到 168,再除以 256 取整得到 1,剩下的 1 就是最后一段。拼起来正好是 192.168.1.1,原路返回,分毫不差。

十六进制是同一个数的另一种写法。0xC0A80101 拆成 C0、A8、01、01 四组,分别是十进制的 192、168、1、1。如果你想顺手把整数、二进制、十六进制三者来回切,进制转换工具 里能看到这些数在不同基底下的样子,对照着理解会更透。

几个容易踩的坑

第一个坑是把字节顺序弄反。第一段是最高有效字节,1.2.3.4 应该是 16909060,不是反着拼出来的 67305985。一旦按小端拼,每个地址都会算错。

第二个坑是段里留前导零。192.168.01.1 看着没毛病,但有些解析器把 01 当八进制读,悄悄改了数值,严格点的解析器干脆拒绝。把零去掉,一段就是普通十进制的 0 到 255。

第三个坑是有符号整数溢出。255.255.255.255 是 4294967295,比有符号 INT 的上限 2147483647 大得多。要存就用无符号 32 位列或者 64 位列,否则 127.x 以上的地址会绕成负数。

小结

IP 转十进制的核心,就是四段各乘 256 的幂再相加,把一个点分地址压成单个长整数;反过来按位拆分就能还原。理解了这层映射,存储、范围比较、geoip 查询这些事都会顺很多。需要现成的换算和校验,直接用工具就好,填错会给清晰报错而不是返回一个错值。


Made by Toolora · Updated 2026-06-13