You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中筛选百万级IP地址是否属于3个CIDR的最快方法

最快的IP筛选方案:选B,别碰A!

绝对是方案B更快,而且差距会非常明显——尤其是你只有3个CIDR的情况下,咱们来掰扯清楚为什么:

先说说方案A为啥拉胯

把CIDR转换成全量IP集合的思路,乍一看简单,但实际完全不适合你的场景:

  • 内存直接爆炸:比如一个/8的CIDR对应16,777,216个IP,光是存这个集合就要占几十MB(甚至更多,取决于语言),要是有几个大前缀的CIDR,你的内存直接扛不住。
  • 预处理慢到离谱:生成全量IP集合本身就要遍历所有可能的IP,大前缀CIDR的生成时间会非常长,完全没必要做这种无用功。
  • 查询效率也没优势:就算你勉强生成了集合,100万次的“是否在集合中”查询,虽然是O(1),但集合的哈希查询本身也有开销,而且前面的预处理成本已经把这条路堵死了。

方案B才是最优解

把CIDR转成起始/结束的整数IP区间,然后逐个检查IP是否在区间内,这才是高效的正确姿势:

  • 预处理成本极低:每个CIDR只需要做一次计算,把IP转成32位整数,再通过子网掩码算出区间的起始和结束值。3个CIDR的话,几毫秒就能搞定所有预处理。
  • 查询效率拉满:把待检查的IP转成整数后,只需要做3次简单的数值比较(判断是否在某个区间内)。100万次查询就是300万次数值比较,这对CPU来说完全是小菜一碟,线性时间O(n),几乎没有额外开销。
  • 内存占用可以忽略:只需要存3对整数,完全不占空间。

给你个简单的Python实现示例

先写两个工具函数:

def ip_to_int(ip: str) -> int:
    """把IP字符串转成32位整数"""
    octets = list(map(int, ip.split('.')))
    return (octets[0] << 24) | (octets[1] << 16) | (octets[2] << 8) | octets[3]

def cidr_to_range(cidr: str) -> tuple[int, int]:
    """把CIDR转成起始和结束的整数IP区间"""
    ip_str, prefix_str = cidr.split('/')
    prefix_len = int(prefix_str)
    ip_int = ip_to_int(ip_str)
    # 计算子网掩码
    mask = (0xFFFFFFFF << (32 - prefix_len)) & 0xFFFFFFFF
    start = ip_int & mask
    end = start | (~mask & 0xFFFFFFFF)
    return (start, end)

然后进行筛选:

# 你的3个CIDR列表
target_cidrs = ["1.0.0.0/25", "xxx.xxx.xxx.xxx/xx", "yyy.yyy.yyy.yyy/yy"]
# 预处理得到区间
ip_ranges = [cidr_to_range(cidr) for cidr in target_cidrs]

# 假设你的100万IP存在这个列表里
raw_ips = ["1.0.0.1", "2.3.4.5", ...]

filtered_ips = []
for ip in raw_ips:
    ip_int = ip_to_int(ip)
    # 遍历区间,找到匹配就停止
    for start, end in ip_ranges:
        if start <= ip_int <= end:
            filtered_ips.append(ip)
            break

这个代码跑100万IP,秒级就能出结果,完全不用担心性能问题。

额外优化小技巧

如果你的CIDR之间有重叠或者包含关系,可以先把区间合并(比如把重叠的区间合并成一个大区间),这样能减少每次查询的判断次数——不过3个CIDR的话,这个优化的收益不大,直接遍历反而更简单。

内容的提问来源于stack exchange,提问作者Jonathan Allen Grant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:32:32