判断ip是否在一个超大ip集中(识别国内ip)

2024-08-24 18:38

本文主要是介绍判断ip是否在一个超大ip集中(识别国内ip),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址: https://www.ikaze.cn/article/65

新需求需要通过ip展示不同语言,由于ip很多,因此字典并不适用,下面给出几个方法。

1. 通过ip位置数据库

比较有名的服务商有:ipip(付费), maxmind (付费),纯真 (免费)。

但在这个应用场景下,我们并不需要具体的位置信息,类似的方案会浪费不必要的内存因此放弃。

2. 利用ip的连续性

后面两个方法有个前提:ip地址列表中大部分是连续的。

这里我们已有了国内ip地址列表(已有开源的库,很好找,另外我用的这个库已经把ip合并为了CIDR格式的地址)。

我们先通过二进制把ip转为可直接比较的数字,再把连续的ip变为 (start_ip, end_ip) 这样的集合,就可以利用二分法快速查找了。

import ipcalcclass ChinaIp:def __init__(self):self.data = []def load(self, cidr_file='data/china_ip_list.txt'):with open(cidr_file, 'r')as f:for s in f.readlines():self.add(s.strip())def add(self, cidr):n = ipcalc.Network(cidr)self.data.append((n.host_first().ip, n.host_last().ip))def search(self, ip):l = 0r = len(self.data) - 1while l <= r:mid = (l + r) // 2if self.data[mid][0] <= ip <= self.data[mid][1]:return Trueelif self.data[mid][0] > ip:r = mid - 1elif self.data[mid][1] < ip:l = mid + 1else:return Falsereturn Falsedef __contains__(self, item):ip = ipcalc.IP(item).ipreturn self.search(ip)china_ip = ChinaIp()
china_ip.load()
print('223.70.163.83' in china_ip)

3. 利用CIDR的特性

CIDR 是形如 x.x.x.x/n 这样的地址,它表示一组网络地址相同的ip,其中n表示前n位作为网络地址。 

根据CIDR的特性,我们可以得到这样的结论:同一CIDR下的ip,其网络地址是相同的。 

因此我们可以把所有国内cidr地址的网络地址取出,放字典;对于一个ip,尝试可能的网络地址(即n),看其是否在字典中。

import ipcalcclass ChinaIp(object):def __init__(self):self.data = {}def load(self, cidr_files='data/china_ip_list.txt'):with open(cidr_files, 'r')as f:cidr_list = f.readlines()for cidr in cidr_list:self.insert(cidr.strip())def insert(self, cidr):network = ipcalc.Network(cidr)self.data[str(network.netmask())]=Truedef __contains__(self, ip):for i in range(1,33):netmask = str(ipcalc.Network(f'{ip}/{i}').netmask())if netmask in self.data:return Truereturn Falsechina_ip = ChinaIp()
china_ip.load()
print('223.70.163.83' in china_ip)

这个算法看起来没啥毛病,但实际测试中速度比第二种慢了很多,耗时的地方在比较时必须循环所有n,而二分法可以快速的排除不可能的部分。

对于这种情况,有两种优化方法:

1. 随机n的列表

class ChinaIp(object):...def __contains__(self, ip):l = list(range(1, 33))random.shuffle(l)for i in l:netmask = str(ipcalc.Network(f'{ip}/{i}').netmask())if netmask in self.data:return Truereturn False

这种方法在测试中,时间减少了一半多。

2. 排除不会出现的n

class ChinaIp(object):def __init__(self):...self.mask_set = set()...def insert(self, cidr):network = ipcalc.Network(cidr)self.data[str(network.netmask())] = Trueself.mask_set.add(network.mask)def __contains__(self, ip):for i in self.mask_set:netmask = str(ipcalc.Network(f'{ip}/{i}').netmask())if netmask in self.data:return Truereturn False

这样优化后速度和第二种持平,不过实际应用中还需要根据ip列表的情况来判断需要用哪种。

这篇关于判断ip是否在一个超大ip集中(识别国内ip)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1103290

相关文章

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

如何通过try-catch判断数据库唯一键字段是否重复

《如何通过try-catch判断数据库唯一键字段是否重复》在MyBatis+MySQL中,通过try-catch捕获唯一约束异常可避免重复数据查询,优点是减少数据库交互、提升并发安全,缺点是异常处理开... 目录1、原理2、怎么理解“异常走的是数据库错误路径,开销比普通逻辑分支稍高”?1. 普通逻辑分支 v

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Linux实现查看某一端口是否开放

《Linux实现查看某一端口是否开放》文章介绍了三种检查端口6379是否开放的方法:通过lsof查看进程占用,用netstat区分TCP/UDP监听状态,以及用telnet测试远程连接可达性... 目录1、使用lsof 命令来查看端口是否开放2、使用netstat 命令来查看端口是否开放3、使用telnet

Linux查询服务器 IP 地址的命令详解

《Linux查询服务器IP地址的命令详解》在服务器管理和网络运维中,快速准确地获取服务器的IP地址是一项基本但至关重要的技能,下面我们来看看Linux中查询服务器IP的相关命令使用吧... 目录一、hostname 命令:简单高效的 IP 查询工具命令详解实际应用技巧注意事项二、ip 命令:新一代网络配置全

Conda国内镜像源及配置过程

《Conda国内镜像源及配置过程》文章介绍Conda镜像源使用方法,涵盖临时指定单个/多个源、永久配置及恢复默认设置,同时说明main(官方稳定)、free(逐渐弃用)、conda-forge(社区更... 目录一、Conda国内镜像源二、Conda临时使用镜像源指定单个源临时指定多个源创建环境时临时指定源

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

Python中图片与PDF识别文本(OCR)的全面指南

《Python中图片与PDF识别文本(OCR)的全面指南》在数据爆炸时代,80%的企业数据以非结构化形式存在,其中PDF和图像是最主要的载体,本文将深入探索Python中OCR技术如何将这些数字纸张转... 目录一、OCR技术核心原理二、python图像识别四大工具库1. Pytesseract - 经典O

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用