判断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

相关文章

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. 使用

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

Python基于微信OCR引擎实现高效图片文字识别

《Python基于微信OCR引擎实现高效图片文字识别》这篇文章主要为大家详细介绍了一款基于微信OCR引擎的图片文字识别桌面应用开发全过程,可以实现从图片拖拽识别到文字提取,感兴趣的小伙伴可以跟随小编一... 目录一、项目概述1.1 开发背景1.2 技术选型1.3 核心优势二、功能详解2.1 核心功能模块2.

Go语言如何判断两张图片的相似度

《Go语言如何判断两张图片的相似度》这篇文章主要为大家详细介绍了Go语言如何中实现判断两张图片的相似度的两种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 在介绍技术细节前,我们先来看看图片对比在哪些场景下可以用得到:图片去重:自动删除重复图片,为存储空间"瘦身"。想象你是一个

Python验证码识别方式(使用pytesseract库)

《Python验证码识别方式(使用pytesseract库)》:本文主要介绍Python验证码识别方式(使用pytesseract库),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全... 目录1、安装Tesseract-OCR2、在python中使用3、本地图片识别4、结合playwrigh

Python如何判断字符串中是否包含特殊字符并替换

《Python如何判断字符串中是否包含特殊字符并替换》这篇文章主要为大家详细介绍了如何使用Python实现判断字符串中是否包含特殊字符并使用空字符串替换掉,文中的示例代码讲解详细,感兴趣的小伙伴可以了... 目录python判断字符串中是否包含特殊字符方法一:使用正则表达式方法二:手动检查特定字符Pytho

Gradle在国内配置镜像加速的实现步骤

《Gradle在国内配置镜像加速的实现步骤》在国内使用Gradle构建项目时,最大的痛点就是依赖下载贼慢,甚至卡死,下面教你如何配置国内镜像加速Gradle下载依赖,主要是通过改写repositori... 目录引言一、修改 build.gradle 或 settings.gradle 的 reposito