检查 IP 列表是否在 IP 范围列表中的快速方法(CIDR 表示法)

Fast way to check if a list of IP is in a list of IP-ranges (CIDR notation)

我正在寻找一种快速方法来检查 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 的信息,但我不确定这是解决方案。

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

有一个 python 实现 here

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

require 'rpatricia'
require 'uoainfoblox'

ib = UoAIinfoblox.new ({'user' => 'xxxxx', 'password' => 'yyyy', 'host' => 'ipam.auckland.ac.nz'})

pt = Patricia.new

ib.get_networks('*roaming_network=true').each do |net, info |
  pt.add(net)
end

puts "'130.216.66.65 #{ pt.include?('130.216.66.65')}"
puts "130.216.5.128 #{pt.include?('130.216.5.128') }"

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

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