检查两个 CIDR 地址是不是相交?

Posted

技术标签:

【中文标题】检查两个 CIDR 地址是不是相交?【英文标题】:Check if two CIDR addresses intersect?检查两个 CIDR 地址是否相交? 【发布时间】:2013-06-16 21:34:31 【问题描述】:

给定两个 CIDR 地址,例如 192.168.2.0/14 和 192.168.2.0/32

如何检查“python2.6”中两个ip地址是否重叠??

我已经通过了 netaddr,它允许检查是否 192.168.2.0 在 CIDR 地址 192.168.2.0/14 by

from netaddr import IPNetwork, IPAddress
bool = IPAddress("192.168.2.0") in IPNetwork("192.168.2.0/14"):

但是如何检查两个 CIDR 地址呢??

我找到了一个参考::How can I check if an ip is in a network in python

【问题讨论】:

仅供参考,192.168.2.0/32 是单个 IP 地址 (192.168.2.0),而不是子网。 你会接受不是 python 特定的答案吗? 感谢信息。我在 python 中需要它,但你的解释可能有用。 我的解释和罗布的解释是一样的。 【参考方案1】:

使用ipaddr:

>>> import ipaddr
>>> n1 = ipaddr.IPNetwork('192.168.1.0/24')
>>> n2 = ipaddr.IPNetwork('192.168.2.0/24')
>>> n3 = ipaddr.IPNetwork('192.168.2.0/25')
>>> n1.overlaps(n2)
False
>>> n1.overlaps(n3)
False
>>> n2.overlaps(n3)
True
>>> n2.overlaps(n1)
False

【讨论】:

感谢图书馆完全符合我的要求。 相同的代码是否也适用于 IPv6 还是仅支持 IPv4? 为 IPv6 工作。 ipaddr.IPNetwork('::192.168.0.0/120').overlaps(ipaddr.IPNetwork('::192.168.0.0/121')) 返回 True,ipaddr.IPNetwork('::192.168.4.0/120').overlaps(ipaddr.IPNetwork('::192.168.0.0/121')) 返回 False Powershell有解决办法吗?【参考方案2】:

我假设您实际上希望两个 CIDR 都代表范围,即使在您的示例中,192.168.2.0/32 仅代表一个地址。另请注意,在 192.168.2.0/14 中,.2.没有意义,因为 14 位前缀没有达到第三个八位字节。

无论如何,有几种方法可以做到这一点。您可能会注意到,要使它们重叠,一个必须始终是另一个的子集:

def cidrsOverlap(cidr0, cidr1):
    return cidr0 in cidr1 or cidr1 in cidr0

或者您可能会注意到,对于重叠的范围,第一个范围的最低地址必须小于或等于第二个范围的最高地址,反之亦然。因此:

def cidrsOverlap(cidr0, cidr1):
    return cidr0.first <= cidr1.last and cidr1.first <= cidr0.last

print cidrsOverlap(IPNetwork('192.168.2.0/24'), IPNetwork('192.168.3.0/24'))
# prints False

print cidrsOverlap(IPNetwork('192.168.2.0/23'), IPNetwork('192.168.3.0/24'))
# prints True

【讨论】:

感谢范围比较工作。还有一件事,你能找出重叠的ip地址吗?? 重叠的ip地址为范围较小的子网:即/后面的数字较大。因此,在 192.168.2.0/23 和 192.168.2.0/24 之间,重叠的地址是 192.168.2.0/24。请记住,CIDR 子网不能“重叠”。它们只能包含或不包含较小的 CIDR 子网。 @AJRedDevil 因为一个总是另一个的子集,所以重叠只是较小的范围。重叠(较小范围)中的第一个地址是max(cidr0.first, cidr1.first)。最后一个地址是min(cidr0.last, cidr1.last)【参考方案3】:

我写了this简单的命令行工具,基于netaddr库。

pip install ipconflict

例子:

ipconflict 10.0.0.0/22 10.0.1.0/24

输出:

conflict found: 10.0.1.0/24 <-> 10.0.1.0/22

【讨论】:

【参考方案4】:

如果手头没有netaddr进行测试,但我认为您可以检查第一个网络的first和last地址是否都包含在第二个网络中:

net_1 = IPNetwork("192.168.2.0/14")
net_2 = IPNetwork("192.168.2.0/32")
if net_1.first in net_2 and net_1.last in net_2:
    # do something

顺便说一句,IPNetwork line 1102 定义了一个 __contains__ 方法。但我不确定line 1127 没有坏掉?如果是,您应该测试并报告错误。

【讨论】:

以上是关于检查两个 CIDR 地址是不是相交?的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode 160. 相交链表

检查 CGRect 是不是与 CGRect 数组相交

检查图像点是不是与圆相交

检查一个 geohash 是不是与另一个 geohash 相交

如何判断两个链表相交及找到第一个相交点

在 OnPaint() 事件中,如何检查给定的矩形是不是与无效区域相交?