问题描述
最近需要去解析ip地址,用的纯真的ip库,格式为:
ip段起始地址 | ip段结束地址 | ip解析结果 |
---|---|---|
0.0.0.0 | 0.0.0.128 | 北京市 北京市 |
这里先转化下ip,方便后续匹配
ip地址包括4个取值范围是0-255,所以就当成四个256进制的数即可
def ip_convert(ip_input=''):
so = ip_input.split('.')
result = 0
i = 0
for s in so:
power = 3 - i
ip = int(s)
result += ip * math.pow(256, power)
i += 1
out = str(int(result)).rjust(10, '0')
return out
然后就是用自己的ip去匹配
def get_ip2(ip='', ip_pool=None):
if ip_pool is None:
ip_pool = []
index = 0
while index < len(ip_pool):
if ip_pool[index][1] < ip:
index += 1
continue
else:
if ip_pool[index][0] <= ip:
return ip_pool[index][2]
else:
return ''
return ''
发现数据处理效率很低,问题也就是俩,一个是数据量太大,ip库貌似70w+数据,另一个就是比数值比较了。首先我这个地址范围是个int,效率还行,然后我想就优化成str,并补了一下位数,发现效率还是不高。那就得考虑优化一下遍历的量级了
遍历优化
分段处理ip库,将整个库划分为20段,大大提升遍历速度
代码都有注释,不再做多余说明
# ip池分组,主要是提升查询效率
# 处理结果 第几组(索引o开始),这组的结束地址
def split_ip(ip_pool=None, num=20):
if ip_pool is None:
ip_pool = []
one_len = len(ip_pool) // num
result = []
for anum in range(0, len(ip_pool), one_len):
temp = np.array([anum, ip_pool[anum][1]])
result.append(temp)
return result
# 分段处理ip,mid_sheet上面函数处理后的
def get_ip(ip='', ip_pool=None, mid_sheet=None):
if ip_pool is None:
ip_pool = []
if mid_sheet is None:
ip_pool = []
for mid_num, mid_val in enumerate(mid_sheet): # 结束地址递增,只需要判断首个结束地址比当前地址大的情况
if mid_val[1] >= ip:
if mid_num == 0:
tme_a = 0 # 回调ip池的开始地址,索引0的开始地址也是0
else:
tme_a = int(mid_sheet[mid_num - 1][0])+1 # 索引非0的开始地址,是上开始地址为个索引的结束地址+1
tme_b = int(mid_sheet[mid_num][0])+1 # 回调ip池的结束地址(左闭右开,所以+1)
for index, con in enumerate(ip_pool[tme_a: tme_b]):
# print(type(ips[0]))
# print(type(ip))
if con[1] < ip:
continue
else:
if con[0] <= ip:
return con[2]
else:
return ''
return ''
return ''