前言
最近在工作中需要对用户输入的ip进行重复性校验,之前处理的都是单ip,直接通过ip字符串比较即可。现在用户输入的是ip+掩码的方式,也就是支持ip范围输入,这样之前的校验方式就行不通了。
那么如何解决呢?我们都知道ip4是通过"点分十进制"来表示的,本质上就是一个二进制的整数,只需要将十进制的表示的IP转换为二进制整数,通过数值进行比较即可。
对于单ip而言,直接转换为整数,对于ip+掩码的形式(也就是ip范围)获取范围的开始值和结束值就可以确定其范围了。
这里介绍如下:
单个ip转换为整数
# ip4转换为int类型
ip4_to_int = lambda ip: sum([256 ** j * int(i) for j, i in enumerate(ip.split('.')[::-1])])
ip+掩码形式的ip获取起始范围
1.原理(以192.168.1.53/27为例)
192.168.1.53的二进制表示
11000000.10101000.00000001.00110101
# ip4转换为int类型
ip4_to_int = lambda ip: sum([256 ** j * int(i) for j, i in enumerate(ip.split('.')[::-1])])
if mask:
# 子网掩码
sub_mask = '0b{0:0<32}'.format(int("".join(['1' for i in range(mask)])))
# 网络地址
network = ip4_to_int(ip) & int(sub_mask, 2) # 与运算,获取网络地址
# 主机地址
host = '0b{0:0>32}'.format(int("".join(['1' for i in range(32 - mask)])))
print(host)
# 广播地址
broad = network | int(host, 2) # 或运算,将主机号置为1
print("network:{}, broad:{}".format(network, broad))
start_ip_int, end_ip_int = network, broad
else: