微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何检查给定的IP地址范围仅包含一个CIDR?

如何解决如何检查给定的IP地址范围仅包含一个CIDR?

我试图编写一个Python脚本,将两个IP地址之间的范围转换为CIDR,

# cidr.py
import argparse
import netaddr
import sys

parser = argparse.ArgumentParser()
parser.add_argument('start_addr')
parser.add_argument('end_addr')
args = parser.parse_args()

start_addr = netaddr.IPAddress(args.start_addr)
end_addr = netaddr.IPAddress(args.end_addr)
if end_addr < start_addr:
  print('start address is larger than end address. check arguments.')
  sys.exit()
ip_cidr = netaddr.iprange_to_cidrs(start_addr,end_addr)

print(str(ip_cidr))

例如,使用Salesforce's IP address range作为参数执行此脚本, 它会返回正确的CIDR表达式。

$ python cidr.py 13.108.0.0 13.111.255.255
[IPNetwork('13.108.0.0/14')]

但是当我修改第二个参数时,它会返回几个CIDR。

$ python hoge.py 13.108.0.0 13.211.255.255
[IPNetwork('13.108.0.0/14'),IPNetwork('13.112.0.0/12'),IPNetwork('13.128.0.0/10'),IPNetwork('13.192.0.0/12'),IPNetwork('13.208.0.0/14')]

我想知道的2个IP地址的地址范围包含1个CIDR表达式。 如何检查?

解决方法

如果iprange_to_cidrs始终返回跨越提供的范围所需的最小IP范围数(看起来很可能),那么您只需要测试它返回的列表的长度即可。

但是,如果您不想验证是否总是这种情况,则可以使用以下方法。

def ip_to_int(ip):
    return sum(256**i * int(v) for i,v in enumerate(reversed(ip.split('.'))))

def single_cidr(ip1,ip2):
    n1 = ip_to_int(ip1)
    n2 = ip_to_int(ip2)
    xor = n2 ^ n1
    return xor == abs(n2 - n1) and '0' not in bin(xor)[2:]

print(single_cidr('13.108.0.0','13.111.255.255'))  # True
print(single_cidr('13.108.0.0','13.211.255.255'))  # False

此处,xor的两个IP(转换为整数)不同时,每个位都包含1。我们希望此数字等于值之间的差,并且也要小于2的幂-这样二进制中的两个IP地址以相同的词干开头,然后一个全为0,另一个全为1。

'0' not in bin(xor)[2:]部分,我们使用以下事实:bin在初始0b之后的输出将以前1位开始,而不会填充任何前导零(例如,对于65535,它将是'0b11111111'),因此我们只需要测试在初始0b之后没有0。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。