如何使用 Python 的 ipaddress 模块来查找子网/ip 是否在更大的子网中?


import ipaddress
from itertools import zip_longest
internal_subnets=[ipaddress.IPv4Network('192.168.0.0/8'),ipaddress.IPv4Network('10.0.0.0/8')]
my_sg_subnets=[ ipaddress.IPv4Network('10.0.19.1/32'),ipaddress.IPv4Network('192.168.20.0/16'), ipaddress.IPv4Network('21.0.19.1/32') ]
for big_subnet, my_ip in zip_longest(internal_subnets, my_sg_subnets):
if not my_ip.subnet_of(big_subnet):
print(f"{my_ip} is not part of {big_subnet}")

如果internal_subnets列表中最后一个子网的None,则此操作失败。那么,如何再次迭代internal_subnet列表中的前两个呢?

最终输出应该是10.0.19.19/32,192.168.20.0/16是internal_subnets的一部分。

请告知。

由于某种原因,您编写的代码使其并行迭代internal_subnetsmy_sg_subnets。它的工作原理是这样的:在第一次迭代中,它从第一个列表中获取第一个元素,从第二个列表中获得第一个元素。在第二次迭代中,它从第一个列表中获取第二个元素,从第二个列表中获得第二个元件,依此类推。相反,您需要遍历internal_subnets,然后检查my_sg_subnets中的任何元素是否为子网。所以这个代码看起来是这样的:

import ipaddress
# Here i don't import itertools because i don't use them here
internal_subnets=[ipaddress.IPv4Network('192.168.0.0/16'), ipaddress.IPv4Network('10.0.0.0/8')]
# I changed network netmask from 8 to 16, because when it's set to 8 python
# just throws an error (Gino Mempin posted a comment about it). I also
# wrote about that below in my post.
# Changing this from 8 to 16 won't affect the actual result in your case (If there was no error) 
my_sg_subnets=[ipaddress.IPv4Network('10.0.19.1'),
ipaddress.IPv4Network('192.168.20.0'),
ipaddress.IPv4Network('21.0.19.1')]
for big_subnet in internal_subnets:
for my_ip in my_sg_subnets:
if my_ip.subnet_of(big_subnet):
# Here instead of printing out everything that is not a subnet,
# it prints out everything that IS a subnet
print(f"{my_ip} is part of {big_subnet}")

而且它的效果和预期的一样。这是输出:

192.168.20.0/32 is part of 192.168.0.0/16
10.0.19.1/32 is part of 10.0.0.0/8

为什么您的代码抛出ValueError:192.168.0.0/8设置了主机位

我们知道每个IP_v4地址只有4个字节的信息,每个IP_v4-网络掩码也是如此。因此,让我们用二进制格式表示1192.168.0.0地址和8网络掩码。

netmask: 11111111 00000000 00000000 00000000 # Netmask of 8 means that it has 8 bits in its beginning 
address: 11000000 10101000 00000000 00000000
˄ ˄ ˄
You can see that this IP address has 1 in place where its netmask has only 
zeros. This should not happen, and this is why python raised this error

例如,如果您的网络的ip地址为1.0.0,网络掩码为8(或更大(,它会工作,如果用二进制表示:

netmask: 11111111 00000000 00000000 00000000
address: 00001010 00000000 00000000 00000000

你会发现一切都很好,因为地址后面没有设置位其网络掩码的末尾。

此外,如果将netmask";7〃;对于网络1.0.0,它也可以工作。但它可能会导致一个你可能不需要的问题,你会看到111.0.0.0地址在这个110.0.0.0网络内

netmask : 11111110 00000000 00000000 00000000
address1: 00001010 00000000 00000000 00000000 # This is 10.0.0.0 addr
address2: 00001011 00000000 00000000 00000000 # This is 11.0.0.0 addr
˄
This bit is different in address1 and address2, but because netmask has 0
at this position, it just doesn't matter, so address2 is inside of network
with address1, because all bits that are under those 1's in the 
netmask are the same.
Your program uses the same algorithm to check if some IP address is 
inside of some network

希望它能让你更好地了解的工作原理

最新更新