用 Python 看一眼 IP 地址的本质:CIDR、子网、私有段都在哪
之前有个同事问我"192.168.1.0/24 到底是几个 IP",我愣了一下——这东西上学时背过,真要写出来反而卡壳。后来我发现,与其死记硬背,不如用 Python 的 ipaddress 模块把这几个概念直接跑一遍。几个最常被搞混的点:CIDR 后面的数字什么意思、私有段到底有哪些、怎么判断两个 IP 是不是一个网段。
CIDR 后面的 /24 到底啥意思
/24 不是"24 个 IP",而是子网掩码里前 24 位是网络号。换句话说,一个 C 段(比如 192.168.1.0/24)固定是 256 个地址,/16 是 65536 个。
import ipaddress
net = ipaddress.ip_network('192.168.1.0/24')
print(net.num_addresses) # 256
print(net.network_address) # 192.168.1.0
print(net.broadcast_address) # 192.168.1.255
network_address 是网段起点,broadcast_address 是广播地址。真实能分配给设备的,其实是中间的 254 个(去掉网络号和广播地址)。
私有段有哪些,怎么判断
IPv4 里常见的私有段就那么几块:
10.0.0.0/8:一个 A 类大私网172.16.0.0/12:16 个 B 类192.168.0.0/16:256 个 C 类,家用路由器基本都在这127.0.0.0/8:回环,本机169.254.0.0/16:链路本地,DHCP 拿不到地址时会自动配
用 ipaddress 一把就能分类,不用自己背:
def classify(ip_str):
ip = ipaddress.ip_address(ip_str)
if ip.is_loopback: return '回环'
if ip.is_private: return '私有'
if ip.is_global: return '公网'
if ip.is_link_local: return '链路本地'
return '其他'
for ip in ['192.168.1.1', '8.8.8.8', '127.0.0.1', '10.0.0.5', '169.254.0.1']:
print(ip, '->', classify(ip))
跑出来是 192.168.1.1 -> 私有、8.8.8.8 -> 公网、127.0.0.1 -> 回环、10.0.0.5 -> 私有、169.254.0.1 -> 私有。注意 169.254 在 ipaddress 里算私有(它确实是保留段),但严格说是链路本地,平时几乎用不到。
子网怎么划
有时候一个 /8 太大,要切成小段分给不同部门。用 subnets() 就行:
subs = list(ipaddress.ip_network('10.0.0.0/8').subnets(new_prefix=16))
print(len(subs)) # 256,也就是 256 个 /16
new_prefix 越大,段越小、数量越多。这是数学关系,不是配置,所以别指望"切一刀能省 IP"。
两个 IP 是不是一个网段
这是排障里最常见的问题:为什么 A 能连 B 但连不上 C?先看看是不是一个子网。
def same_subnet(a, b, prefix):
na = ipaddress.ip_network(f'{a}/{prefix}', strict=False)
nb = ipaddress.ip_network(f'{b}/{prefix}', strict=False)
return na.network_address == nb.network_address
print(same_subnet('192.168.1.10', '192.168.1.200', 24)) # True
print(same_subnet('192.168.1.10', '192.168.2.10', 24)) # False
strict=False 很关键:它会容忍你给的 IP 不是网段起点(比如 192.168.1.10/24),自动归到 192.168.1.0/24,不然直接报错。
一点体会
这些东西教科书上讲得很绕,但落到 ipaddress 里其实就是几个属性和方法。is_private、is_global、num_addresses、subnets() 这几个记住,平时排障、写网络相关脚本基本够用了。
我自己的习惯是:每次配新网段,先用 ip_network 跑一遍确认地址范围,避免把广播地址也配进去了——这种低级错误我犯过不止一次。
浙公网安备 33010602011771号