簡體   English   中英

python netaddr找到最接近的ip地址匹配

[英]python netaddr find closest Ip address match

如何使用相同前綴長度的python netaddr找到最接近的匹配項?

>>> 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
>>>

您似乎在這里遺漏了一個關鍵點:您說“所有三個ip子網都是同一網絡172.27.145.128/25的一部分”,但這是不正確的。 它們都是同一個網絡,只是其名稱不同而已。 這就是IP網絡的工作方式:對於N位網絡,基址的最后N位無關緊要。 因此,無法將它們彼此進行對比,並找出哪一個是“最長”或“最接近”或任何其他類型的匹配,因為它們都是完全相同的匹配。

您可能會說這些是接口 ,而不是網絡。 的界面具有一個網絡,例如內的一個地址,地址172.27.145.130在網絡172.27.145.128/25 您可以使用速記127.27.145.130/25進行指定。 是的,接口的簡寫形式看起來與網絡的簡寫形式相同,但是它們不是一回事。

如果仍然無法獲得地址,網絡和接口之間的區別,那么3.3+ Python文檔提供了很棒的HOWTO

盡管netaddr不支持任何接口,但Python 2.6-2.7的stdlib的ipaddress和第三方ipaddress backport可以。 例如:

>>> 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網絡對象用作netaddr接口對象(盡管實際上,最好使用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位的int,因此您可以將這些IPAddress和在一起,然后以數字方式(而不是字符串)對這些位進行計數。 但是希望這可以清楚地顯示事物。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM