【问题标题】:Find if IP in set of ip addresses and ip networks查找 IP 地址和 IP 网络集中的 IP
【发布时间】:2020-08-24 20:26:04
【问题描述】:

我有一个包含 ip4 地址和 ip4 网络的集合。

简单的例子:

{'127.0.0.1', '138.56.76.02', '192.4.2.0/24', '29.24.48.80', etc, etc, etc}

实际大小是几千件。

问题是 - 检查特定 ip 地址'xxx.yyy.zzz.lll' 是否包含在所有这些 ip 地址和 ip 网络的混合中而不逐个遍历它们的最快方法是什么?

使用普通 ips 设置很明显,但存在 ip 网络则不是这样,因为网络也可能包含此 ip。

也可以有相同的设置,但内部的 ips 和网络包含在 ipaddress 包中的 IPv4AddressIPv4Network 对象中。

也许有可能以某种方式将所有这些组合到一个伪网络中???

谢谢...

【问题讨论】:

标签: python ip


【解决方案1】:

一种方法是使用ipaddress 模块来构建setIPv4Address 实例:

>>> from ipaddress import *
>>> from itertools import *
>>>
>>> p = {'127.0.0.1', '138.56.76.02', '192.4.2.0/24', '29.24.48.80', ...}
>>>
>>> all_hosts = set(chain.from_iterable(IPv4Network(n) for n in p))
>>>
>>> IPv4Address('192.4.2.4') in all_hosts
True
>>> IPv4Address('29.24.48.80') in all_hosts
True
>>> IPv4Address('29.24.48.81') in all_hosts
False

这利用了这样一个事实,即仅从一个地址(没有掩码)构建 IPv4Network 会创建一个仅包含该地址的网络。它还使用了迭代 IPv4Network 的功能,依次为您提供每个主机。

如果 p 很大或网络掩码包含许多主机,all_hosts 集的构建速度会很慢并且内存很大。然而,在那之后,检查一个 IP 地址是否在集合中会很快(平均 O(1))。

如果p 已经包含IPv4NetworkIPv4Address 实例,所有这些仍然有效。

【讨论】:

  • 感谢您的回答。我想到了类似的东西。但是您不认为在为集合中的每个对象创建 IPv4Network 之后创建 IPv4Address 实例会很慢吗? Mybe 最好从集合中过滤掉网络(或多或少 10% 到 90%),然后将网络扩展到单个 ips 列表而不将它们转换为 IPv4Network 和 IPv4Address ?
  • 唯一确定的方法是测量。您可以使用timeit module 或仅使用秒表来查看构建all_hosts 的方式更快,然后考虑您在程序中重建all_sets 的频率并确定差异是否足够大以值得额外复杂性。
【解决方案2】:

我建议使用列表并这样做:

if "xxx.yyy.zzz.ttt" in ip_list:
    print("IP IN LIST")

问候。

【讨论】:

    猜你喜欢
    • 2019-02-03
    • 2014-05-25
    • 2015-12-06
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 2021-05-31
    • 2019-06-13
    • 2012-06-28
    相关资源
    最近更新 更多