您应该为此使用 stdlib ipaddress。不要试图用原始字符串操作来做,因为有几个陷阱和奇怪的边缘情况。使用面向对象的库可以防止生成无效数据。
将 ipv4 地址从 192.168.1.0 迭代到 192.168.1.255(含)相当于迭代 192.168.1.0/24 subnet。使用network 对象:
>>> from ipaddress import ip_network
>>> list(ip_network('192.168.1.0/24'))
[IPv4Address('192.168.1.0'),
IPv4Address('192.168.1.1'),
IPv4Address('192.168.1.2'),
...
IPv4Address('192.168.1.255')]
其中一些地址不是可用的主机,例如 255 是broadcast address。如果这是您要查找的内容,请迭代 hosts:
>>>> list(ip_network('192.168.1.0/24').hosts())
[IPv4Address('192.168.1.1'),
IPv4Address('192.168.1.2'),
IPv4Address('192.168.1.3'),
...
IPv4Address('192.168.1.254')]
请注意,192.168.1.999 不是有效的 IP 地址,所以不要生成它!验证器将阻止您创建它:
>>> from ipaddress import ip_address
>>> ip_address('192.168.1.254')
IPv4Address('192.168.1.254')
>>> ip_address('192.168.1.999')
# ValueError: '192.168.1.999' does not appear to be an IPv4 or IPv6 address
要将ip address object 转换回普通的旧字符串,只需调用str 即可。
您的问题还询问了“翻转”到 192.168.2.1。这只是迭代不同的子网。 192.168.1.0/24 中的 24 是指为网络前缀分配的 24 位有效位(其余 8 位保留用于主机寻址),即 子网掩码 255.255.255.0。
为了让它“翻转”,你真的只想迭代一个更大的子网:
>>> gen = iter(ip_network('192.168.0.0/16'))
>>> for i in range(255*2):
... next(gen)
...
>>> next(gen)
IPv4Address('192.168.1.254')
>>> next(gen)
IPv4Address('192.168.1.255')
>>> next(gen)
IPv4Address('192.168.2.0')
>>> next(gen)
IPv4Address('192.168.2.1')
要从单个ip地址字符串获取网络对象,可以使用supernet方法:
>>> from ipaddress import ip_address, ip_interface
>>> ip = ip_address('192.168.1.1')
>>> net = ip_interface(ip).network
>>> net
IPv4Network('192.168.1.1/32')
>>> net.supernet(prefixlen_diff=8)
IPv4Network('192.168.1.0/24')
阅读 Internet Protocol version 4 了解更多信息,以及 Python 的 ipaddress 模块的官方文档。