我有一组约200,000个IP地址和10,000个子网(1.1.1.1/24)。对于每个IP地址,我需要检查它是否属于这些子网之一,但由于它是一个如此庞大的数据集,而且我的计算能力较低,所以我希望为此进行有效的实施。如何有效地检查给定的IP地址是否属于Python中的IP子网?
上进行搜索,一个方法,我发现了这个(https://stackoverflow.com/a/820124/7995937):
from netaddr import IPNetwork, IPAddress
if IPAddress("192.168.0.1") in IPNetwork("192.168.0.0/24"):
print "Yay!"
但因为我有循环这个超过20万IP地址,每个地址循环超过10,000子网,我不能确定这是否是高效的。 我的第一个疑问是,检查IPNetwork()中的“IPAddress()”是线性扫描还是以某种方式优化?
我想出的另一个解决方案是制作IP子网中包含的所有IP列表(其中包含大约13,000,000个IP,没有重复),然后对其进行排序。如果我这样做,那么在循环遍历200,000个IP地址时,我只需要通过一组更大的IP地址对每个IP进行二进制搜索。
for ipMasked in ipsubnets: # Here ipsubnets is the list of all subnets
setUnmaskedIPs = [str(ip) for ip in IPNetwork(ipMasked)]
ip_list = ip_list + setUnmaskedIPs
ip_list = list(set(ip_list)) # To eliminate duplicates
ip_list.sort()
然后我可以进行以下方式的二进制搜索:
for ip in myIPList: # myIPList is the list of 200,000 IPs
if bin_search(ip,ip_list):
print('The ip is present')
是这种方法比其他方法更有效?或者还有没有其他更有效的方式来执行这项任务?
如前所述,最快的是使用集合。关于它的其他主题: https://stackoverflow.com/questions/5993621/fastest-way-to-search-a-list-in-python –
把一个IPv4字符串变成一个32位的int是微不足道的,所以如果我必须创建一个类似于我可能在内部使用整数和二元运算符的库,这将非常有效。像往常一样,您应该先测量一下是否确实存在性能问题。 – polku