【问题标题】:Fast way to check if a list of IP is in a list of IP-ranges (CIDR notation)检查 IP 列表是否在 IP 范围列表中的快速方法(CIDR 表示法)
【发布时间】:2017-10-24 12:35:13
【问题描述】:

我正在寻找一种快速的方法来检查 IP 地址是否属于 CIDR 标记的 IP 范围列表的一部分。我在使用 netaddr 之前看过一些示例,例如:

from netaddr import IPNetwork, IPAddress

    for CIDR in CIDRLIST:
        if IPAddress(row[0]) in IPNetwork(CIDR):
            print('success')

但是这个解决方案对于我的问题来说太慢了(CIDR 中有 800 个 IP 范围和 500.000 个 IP 地址)。

有什么方法可以更快地做到这一点?我已经阅读了有关使用 pytries 的信息,但我不确定这是否是解决方案。

【问题讨论】:

  • 使用列表推导而不是循环,看看是否能提高性能。
  • 我想知道您是否可以在 python 中实现具有任何性能的“Van Emde Boas Tree”。
  • 我有同样的问题——我很确定答案是将块列表预处理成树,然后搜索树。自从我研究这些东西已经 40 年了,我将不得不去查阅 Knuth 第 3 卷。谢天谢地,IT 中的一些事情没有改变!我不认为 vEB 树会很好地工作,因为您需要为块中每个可能的 IP 构建带有密钥的树。 (假设我正确理解了维基百科的文章)。

标签: python-3.x performance ip-address lookup cidr


【解决方案1】:

Patricia/​​Radix tree/tries 似乎是答案。我通过搜索查找路由表的算法找到了它们。

有一个python实现here

稍后:我现在在 Ruby 中可以正常工作:

需要'rpatricia' 需要'uoainfoblox' ib = UoAIinfoblox.new ({'user' => 'xxxxx', 'password' => 'yyyy', 'host' => 'ipam.auckland.ac.nz'}) pt = Patricia.new ib.get_networks('*roaming_network=true').each 做 |net, info | pt.add(净) 结尾 将“'130.216.66.65 #{ pt.include?('130.216.66.65')}” 提出“130.216.5.128 #{pt.include?('130.216.5.128') }”

Infoblox 是一个 IP 管理系统,而 UoAInfoblox 是其 Web api 的包装器。所以在这里我得到一个漫游网络列表,将它们添加到帕特里夏树中,然后检查两个 IP 地址(我知道它们的状态)。

编辑:我刚刚从一位使用 python 的朋友那里得知,他在我们的 CS 部门教授网络,他在他的研究脚本中使用了 python 基数模块。我知道他正在为 CAIDA 处理来自 /8 暗网的大量数据。

【讨论】:

    猜你喜欢
    • 2014-09-16
    • 2015-11-08
    • 2012-03-26
    • 2011-06-23
    • 2017-01-14
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多