Python模块学习 - IPy
简介
在IP地址规划中,涉及到计算大量的IP地址,包括网段、网络掩码、广播地址、子网数、IP类型等,即便是专业的网络人员也要进行繁琐的计算,而IPy模块提供了专门针对IPV4地址与IPV6地址的类与工具,可以帮助实现计算子网掩码、网络掩码、广播地址、子网数、IP类型等。
# 安装ipy pip3 install ipy
基本使用
ipy模块内部主要主要提供了IP类、IPint类,IPset类,我们常用的就是IP类,这个类可以接受几乎任何格式的IP地址和网段。
常用方法
version():获取IP地址的版本
>>> from IPy import IP >>> IP('10.0.0.1').version() 4 >>> IP('10.0.0.0/24').version() 4 >>> IP('::1').version() 6 # 4 表示 IPv4, 6 表示 IPv6
len():获取子网IP地址的个数
>>> from IPy import IP >>> ip = IP('10.0.0.0/27') >>> ip.len() 32 # 纯的IP个数,我们需要排除网络地址和广播地址,所以可用地址是30个
iptpe():获取IP地址的类型
>>> from IPy import IP >>> ip = IP('10.0.0.1') >>> ip.iptype() 'PRIVATE' >>> ip = IP('8.8.8.8') >>> ip.iptype() 'PUBLIC' # PRIVATE 表示私有地址, PUBLIC 表示公有地址
int():返回IP地址的整数格式
>>> from IPy import IP >>> ip = IP('10.0.0.1') >>> ip.int() 167772161
strHex():返回IP地址的十六进制格式
>>> from IPy import IP >>> ip = IP('10.0.0.1') >>> ip.strHex() '0xa000001'
strBin():返回IP地址的二进制格式
>>> from IPy import IP >>> ip = IP('10.0.0.1') >>> ip.strBin() '00001010000000000000000000000001'
PS:在数据库中存储IP地址有两种形式:
- 以变长字符串的形式将IP地址保存在数据库中
- 将IP地址转换为整数以后保存到数据库中
转换成整数后进行存储可以有效的节省存储空间,提高数据库的存储效率和访问速度,所以在最佳实践中,一般将IP地址以数字的形式保存到数据库中。当需要IP地址时,我们再对整数的IP地址进行转换即可。
mysql本身也提供了IP地址到证书的转换函数:
mysql> select inet_aton('10.0.0.1') -> ; +-----------------------+ | inet_aton('10.0.0.1') | +-----------------------+ | 167772161 | +-----------------------+ 1 row in set (0.00 sec) mysql> select inet_ntoa('167772161'); +------------------------+ | inet_ntoa('167772161') | +------------------------+ | 10.0.0.1 | +------------------------+ 1 row in set (0.00 sec) mysql>
而在Python中,通过int方法就可以进行转换
>>> from IPy import IP >>> ip = IP('167772161') >>> ip IP('10.0.0.1') >>> # 转换成数字使用 int方法 即可
网段管理
IP类的构造函数可以接受多种类型的IP地址或者是一个网段格式。
>>> from IPy import IP >>> IP('172.16.0.0/16') IP('172.16.0.0/16') >>> IP('172.16.0.0-172.31.255.255') IP('172.16.0.0/12') >>> IP('10.0.0.0/255.0.0.0') IP('10.0.0.0/8') >>> # 当IP类的实例化参数是一个网段时,那么参数的主机地址必须为0,否则会提示IP地址前缀错误
对于包含多个IP地址的对象,我们可以调用len方法或者内置的len方法,求出IP地址的个数
>>> from IPy import IP >>> ip = IP('10.0.0.0/255.0.0.0') >>> ip.len() 16777216 >>> len(ip) 16777216 >>>
对于网段的地址,我们也可以利用for循环,得到其包涵的所有IP地址
>>> from IPy import IP >>> ip = IP('10.0.0.0/30') >>> for i in ip: print(i) 10.0.0.0 10.0.0.1 10.0.0.2 10.0.0.3 >>>
针对不同的显示方式,还可以使用strNormal方法,该方法接受一个 wantprefixlen 参数,参数的合法取值为 0 - 3,每一个取值表示一种显示方式
>>> from IPy import IP >>> ip = IP('10.0.0.0/30') >>> ip.strNormal(0) '10.0.0.0' >>> ip.strNormal(1) '10.0.0.0/30' >>> ip.strNormal(2) '10.0.0.0/255.255.255.252' >>> ip.strNormal(3) '10.0.0.0-10.0.0.3' >>>
针对于网段而言,还可以获取其子网掩码,以及广播地址
>>> from IPy import IP >>> ip = IP('10.0.0.0/30') >>> ip.netmask() IP('255.255.255.252') >>> ip.broadcast() IP('10.0.0.3') >>>
还可以进行ip的判断,判断其是否属于一个网段中,又或者两个网段中是否重叠
>>> from IPy import IP >>> IP('10.0.0.1') in IP('10.0.0.0/24') True >>> IP('192.168.0.1') in IP('10.0.0.0/24') False >>> IP('10.0.0.0/24').overlaps('192.168.0.0/24') 0 >>> IP('10.0.0.0/8').overlaps('10.0.0.0/16') 1 >>> # 0 表示不包涵,1表示包涵
所有巧合的是要么是上天注定要么是一个人偷偷的在努力。