为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

幕布斯6054654 2023-07-11 15:29:29
我试图编写一个Python脚本将两个IP地址之间的范围转换为CIDR,# cidr.pyimport argparseimport netaddrimport sysparser = 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 的 IP 地址范围作为参数执行此脚本,它会返回正确的 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表达式。我该如何检查?
查看完整描述

1 回答

?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

如果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 的幂小 1,这样二进制中的两个 IP 地址都以相同的词干开头,然后一个全 0,另一个全 1。


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


查看完整回答
反对 回复 2023-07-11
  • 1 回答
  • 0 关注
  • 55 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信