2014-11-25 62 views
0

我怎樣才能找到最接近的匹配使用python netaddr相同的前綴長度?蟒蛇netaddr找到最接近的ip地址匹配

>>> l = ['172.27.145.130/25', '172.27.145.129/25', '172.27.145.131/25'] 
>>> myip = '172.27.145.129' 
>>> netaddr.IPAddress(myip) in netaddr.IPNetwork(l[0]) 
True 
>>> netaddr.IPAddress(myip) in netaddr.IPNetwork(l[1]) 
True 
>>> netaddr.IPAddress(myip) in netaddr.IPNetwork(l[2]) 
True 
>>> 
+0

「最接近的匹配」是什麼意思?這些都是非法網絡,或者是同一網絡中的不同名稱,具體取決於你想要定義事物的嚴格程度,所以它們都不比任何其他網絡更接近。 – abarnert 2014-11-25 01:00:54

+0

以及最接近的比賽,我的意思是最長的比賽。對不起,混淆 – abarik 2014-11-25 01:12:03

+1

OK,那麼「最長匹配」是什麼意思?同樣,所有這三個人都定義了完全相同的CIDR網絡172.27.145.128/25,或者根本沒有,所以我不知道你期望得到什麼不同的結果。 – abarnert 2014-11-25 01:18:41

回答

1

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

還有其他的方法來解決這個。例如,每個IPAddressvalue是一個32位整數,因此您可以將它們組合在一起並以位數的形式對位進行計數,而不是字符串。但希望這可以明確地表明事情。