python之ipv4的ip转换为int数值

2019-07-07  本文已影响0人  white_study

前言

最近在工作中需要对用户输入的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
子网掩码 11111111.11111111.11111111.11100000 27表示有27个1
网络地址 11000000.10101000.00000001.00100000 子网掩码与ip地址进行与运算,得到网络地址(与运算就是全1为1,其它都为0)
广播地址 11000000.10101000.00000001.00111111 在网络地址的基础上,将主机地址全部填充为1

其中网路地址就是ip段的开始值,广播地址就是ip段的结束值.

2.具体代码实现
def get_ip_mask_range(ip, mask):
    """获取掩码ip的整数范围(包括网络地址和广播地址)"""

    # 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:
        start_ip_int = end_ip_int = ip4_to_int(ip)

    return start_ip_int, end_ip_int

喜欢点个赞!!!

上一篇下一篇

猜你喜欢

热点阅读