你似乎在這裏失去了一個關鍵點:你說,「所有三個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