你似乎在这里失去了一个关键点:你说,“所有三个IP子网是相同的网络172.27.145.128/25的一部分”,但事实并非如此;它们全都是都是那个网络,只是它的不同非标准名称。这就是IP网络的工作方式:对于N位网络,基地址的最后N位无关紧要。所以没有办法将他们与对方进行对比,并找出哪一个是“最长”或“最接近”或任何其他类型的匹配,因为它们都将完全相同。
这可能是你的意思是接口,而不是网络。一个接口在网络中有一个地址 - 例如,网络172.27.145.128/25
中的地址172.27.145.130
。你可以用简写127.27.145.130/25
来指定。是的,接口的简写形式看起来与网络的简写形式相同,但它们不是一回事。
如果你仍然没有得到地址,网络和接口之间的区别,3.3+ Python文档有一个很好的HOWTO。
虽然netaddr
没有对接口的任何支持,STDLIB的ipaddress
和第三方ipaddress
反向移植的Python 2.6-2.7,做的。例如:
>>> l = ['172.27.145.130/25', '172.27.145.129/25', '172.27.145.131/25']
>>> interfaces = [ipaddress.ip_interface(x) for x in l]
>>> interfaces[0]
IPv4Interface('172.27.145.130/25')
>>> interfaces[0].ip, interfaces[0].network
(IPv4Address('172.27.145.130'), IPv4Network('172.27.145.128/25'))
因此,也许你问的是哪个接口与给定地址共享最多位? (我仍然不确定这是你的意思,“最接近的匹配”还是“最长的匹配”,但这似乎是一个合理的猜测。)
这仍然是一个模棱两可的问题。您可以要求询问哪个接口的地址共享更多的位周期,或者哪个共享更多的位在子网内。但是由于它们都在同一个子网中,所以这并不重要。
这意味着我们甚至可以使用netaddr
网络对象作为ersatz接口对象(尽管真的,最好使用ipaddress
或其他实际支持接口对象的库)。
所以:
>>> l = ['172.27.145.130/25', '172.27.145.129/25', '172.27.145.131/25']
>>> interfaces = [netaddr.IPNetwork(interface) for interface in l]
>>> addresses = [interface.ip for interface in interfaces]
>>> bits = [address.bits() for address in addresses]
>>> bits
['10101100.00011011.10010001.10000010',
'10101100.00011011.10010001.10000001',
'10101100.00011011.10010001.10000011']
>>> myip = '172.27.145.129'
>>> myaddress = netaddr.IPAddress(myip)
>>> mybits = myaddress.bits()
'10101100.00011011.10010001.10000001'
(很明显,你可以让整个事情就是二,三线合并在一起大多数的这些步骤)
而现在我们只是比较字符串。
但netaddr.IPAddress
也有一个&
运营商,所以我们可以让它更简单:
>>> common_bits = [(address & myaddress).bits() for address in addresses]
>>> common_bits
['10101100.00011011.10010001.10000000',
'10101100.00011011.10010001.10000001',
'10101100.00011011.10010001.10000001']
>>> common_bit_counts = [bits.count('1') for bits in common_bits]
>>> common_bit_counts
[12, 13, 13]
还有其他的方法来解决这个。例如,每个IPAddress
的value
是一个32位整数,因此您可以将它们组合在一起并以位数的形式对位进行计数,而不是字符串。但希望这可以明确地表明事情。
“最接近的匹配”是什么意思?这些都是非法网络,或者是同一网络中的不同名称,具体取决于你想要定义事物的严格程度,所以它们都不比任何其他网络更接近。 – abarnert 2014-11-25 01:00:54
以及最接近的比赛,我的意思是最长的比赛。对不起,混淆 – abarik 2014-11-25 01:12:03
OK,那么“最长匹配”是什么意思?同样,所有这三个人都定义了完全相同的CIDR网络172.27.145.128/25,或者根本没有,所以我不知道你期望得到什么不同的结果。 – abarnert 2014-11-25 01:18:41