如何检查IP地址是否在python中的网络列表中的任何网络中?

时间:2015-05-06 19:11:46

标签: python algorithm

所以,对于单一搜索:

using (FileStream fs = new FileStream(downloadPath, FileMode.Open, FileAccess.Read))
{
    byte[] buffer = new byte[2];
    fs.Read(buffer, 0, buffer.Length);
    if (buffer[0] == 0x1F
        && buffer[1] == 0x8B)
    {
        // It's probably a GZip file
    }
    else
    {
        // It's probably not a GZip file
    }
}

但是,如果您获得了网络列表,该怎么办?是否可以在不使用for循环的情况下完成?什么是pythonic方式来完成这项任务? ...最好是可读的,然后更快。

from netaddr import IPAddress, IPNetwork
if IPAddress( address ) in IPNetwork( network ):
    print( 'in' )

编辑:对于任何有兴趣的人,我都拿了我给定的网络列表,并将每个网络扩展到其地址列表。然后我拿了那个地址列表并从中制作了一套。鉴于集合具有O(1)查找,我认为它会有所帮助。

完成for循环所需的时间(无设定)为24分钟 使用时间:

from netaddr import IPAddress, IPNetwork
networks = [
    '1.0.0.0\8',
    '2.0.0.0\8',
    # ...
    '21.22.14.0\24' # something random
]

for network in networks:
    if IPAddress( address ) in IPNetwork( network ):
        print( 'in' )
        break

...是2分37秒。

GO SETS!

请注意:扩展网络可能会耗费内存。

2 个答案:

答案 0 :(得分:1)

if any(IPAddress(address) in IPNetwork(network) for network in networks):
   ...

优化可以通过仅实例化IPAddress一次,并将IPNetwork存储在列表中来完成。

答案 1 :(得分:0)

(这些都不是特定于Python的,所以如果这个问题真的是关于语法和编码风格,这个答案对此没什么贡献。基本上,它扩展了我认为abarnert在评论中建议的内容。)< / p>

这里不需要以制定基本假设和构建搜索树为代价来循环所有范围:假设您要检查的范围是非重叠的(即没有两个范围包含某些共享IP),可以为您的范围构建搜索树,然后在适当调整树的搜索功能后,在您的有序范围集中的O(log n)中搜索IP(甚至范围),这非常简单。

如果您有重叠范围,您可能需要查看间隔树,您应该可以非常轻松地应用于该情况。

两者只有在您需要查询许多次要维护的非常多网络时才有用。如果你实际上只需要随时处理50个网络,这应该是微不足道的,并且可以在列表内立即工作。