IPy-IPv4和IPv6地址处理模块学习笔记

IPy-IPv4和IPv6地址处理模块学习笔记在日常网络规划中 会有很多关于 IP 地址的分配规划问题 如果是手动分配 在量很大的情况下 容易出错 而利用 IPy 这个 python 模块 可以很容易实现对 iP 地址的分配等操作 IPy 用于处理 IPv4 和 IPv6 地址和网络的类和工具

在日常网络规划中,会有很多关于IP地址的分配规划问题,如果是手动分配,在量很大的情况下,容易出错。而利用IPy这个python模块,可以很容易实现对iP地址的分配等操作。

以下是对IPy模块学习的一个记录。

IPy模块简介

主要用处:

IPy-用于处理IPv4和IPv6地址和网络的类和工具。

IPy相关:

IPy源码: https://github.com/autocracy/python-ipy/

IPy类和方法

IPy主要有如下类和方法:

dir(IPy) Out[8]: ['INT_TYPES', 'IP', 'IPSet', 'IPV6_MAP_MASK', 'IPV6_TEST_MAP', 'IPint', 'IPv4ranges', 'IPv6ranges', 'MAX_IPV4_ADDRESS', 'MAX_IPV6_ADDRESS', 'STR_TYPES', '_BitTable', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', '_checkNetaddrWorksWithPrefixlen', '_checkNetmask', '_checkPrefix', '_count0Bits', '_count1Bits', '_countFollowingZeros', '_intToBin', '_ipVersionToLen', '_netmaskToPrefixlen', '_parseAddressIPv6', '_prefixlenToNetmask', '_remove_subprefix', 'bisect', 'collections', 'intToIp', 'parseAddress', 'sys', 'types', 'xrange'] 

其中有IPint,IP,IPSet是三个类。

一般都使用IP类,IP类是IPint的代替,IP类继承IPint类。

INT_TYPES,IPV6_MAP_MASK,IPV6_TEST_MAP,IPv4ranges, IPv6ranges,MAX_IPV4_ADDRESS,MAX_IPV6_ADDRESS,STR_TYPES这都是定义的常量。

IPint类 class IPint(object):

处理返回整数的IP地址。

因为IP类继承自IPint,所以IPint类中的方法在IP类中同样适用。

下面会记录常用方法。

__init__(self, data, ipversion=0, make_net=0)

  • data可以是常见的IPv4和IPv6地址的各种表现形式。支持前缀表示,IP段表示,小数点掩码表示,单个IP等。

    也可以输入10进制的进制,2进制的地址等。

  • ipversion可以制定地址的版本,版本为4或者6,输入其他会报错。
  • mask_net如果是为Ture,则可以通过指定掩码来分配IP地址。

测试如下:

>>> print(IP('127.0.0.0/8')) 127.0.0.0/8 >>> print(IP('127.0.0.0/255.0.0.0')) 127.0.0.0/8 >>> print(IP('127.0.0.0-127.255.255.255')) 127.0.0.0/8 >>> print(IP('127.0.0.1/255.0.0.0', make_net=True)) 127.0.0.0/8 [39]: from IPy import IPint ip = IPint('192.168.1.0/24',make_net=True) ip Out[41]: IPint('192.168.1.0/24') for x in ip: print(x)   #返回的是整数类型的IP地址。    ... 

常用方法:

#实例化一个IP地址 ip = IPint('192.168.1.0/24') ip.int() #返回第一个长整型的IP地址 Out[52]:  ip.version() #返回ip的版本号 Out[53]: 4 ip.prefixlen() #返回掩码长度 Out[54]: 24 ip.net() #返回第一个长整型的IP地址 Out[55]:  ip.broadcast() #返回长整型的广播地址 Out[56]:  ----------------------------------------- _printPrefix(self, want): #按输入的want打印掩码 ip._printPrefix(0) #want == 0,None,什么也不返回 Out[58]: '' ip._printPrefix(1) #want == 1, 返回前缀形式的掩码 Out[59]: '/24' ip._printPrefix(2) #want == 2,返回小数点的掩码 Out[60]: '/255.255.255.0' ip._printPrefix(3) #want == 3,返回网络号的最后一个地址 Out[61]: '-192.168.1.255' ipv6 = IPint('2003::/64') ipv6._printPrefix Out[70]: <bound method IPint._printPrefix of IPint('2003::/64')> ipv6._printPrefix(0) Out[71]: '' ipv6._printPrefix(1) Out[72]: '/64' ipv6._printPrefix(2) Out[73]: '/ffff:ffff:ffff:ffff:0000:0000:0000:0000' ipv6._printPrefix(3) Out[74]: '-2003:0000:0000:0000:ffff:ffff:ffff:ffff' -------------------------------------- #可以将IP地址转化为多种类型的字符串。 ipv6.strBin() #返会IPv4或者IPv6的2进制形式字符串 Out[79]: '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' ipv6.strCompressed() #返会简写的形式的地址,主要针对IPv6有效果 Out[80]: '2003::/64' ipv6.strDec() #返会10进制的地址形式 Out[81]: '86720' ipv6.strFullsize() #返会完整形式的地址格式。 Out[82]: '2003:0000:0000:0000:0000:0000:0000:0000/64' ipv6.strHex() #返会16进制形式的地址 Out[83]: '0x000000000000000000000' ipv6.strNetmask() #返会掩码长度 Out[84]: '/64' ipv6.strNormal(wantprefixlen = None) #可以按输入的wantprefixlen来转化为字符串 ipv6.strNormal(wantprefixlen = 0) #不输出掩码 Out[92]: '2003:0:0:0:0:0:0:0' ipv6.strNormal((wantprefixlen = 1) #输出前缀掩码 Out[93]: '2003:0:0:0:0:0:0:0/64' ipv6.strNormal((wantprefixlen = 2) #输出网络掩码 Out[94]: '2003:0:0:0:0:0:0:0/ffff:ffff:ffff:ffff:0000:0000:0000:0000' ipv6.strNormal(3) #输出地址段 Out[95]: '2003:0:0:0:0:0:0:0-2003:0000:0000:0000:ffff:ffff:ffff:ff --------------------------------------- ip.iptype() #返会IP地址的类型 Out[98]: 'PRIVATE' ip2 = IPint('1.1.1.1') ip2.iptype() Out[100]: 'PUBLIC' print(IP('127.0.0.1').iptype()) Out[101]: LOOPBACK print(IP('::1').iptype()) Out[102]: LOOPBACK print(IP('2001:0658:022a:cafe:0200::1').iptype()) Out[103]: ALLOCATED RIPE NCC ----------------------------------------- ip.netmask() #返会整型形式的掩码 Out[104]:  ip.strNetmask() #返会字符串形式的掩码 Out[105]: '255.255.255.0' ip.len() #返会子网的长度 Out[106]: 256 IP('10.1.1.0/28').len() Out[108]: 16 ---------------------------------------- ip.__getitem__(1) #返会网络号中第i个地址。 Out[120]:  ip.__getitem__(2) Out[121]:  ip.__getitem__(3) Out[122]:  ip Out[124]: IPint('192.168.1.0/24') ip.__contains__('192.168.1.1') #判断一个地址是否在这个网段中 Out[125]: True ip.__contains__('192.168.2.1') Out[126]: False '192.168.1.1' in ip Out[127]: True '192.168.3.1' in ip Out[128]: False ------------------------------------------ #检查给定IP地址是否在这个实例化的IP地址返回内  def overlaps(self, item): #如果不重叠,返会0; #如果给定地址在这个实例化的IP地址范围内返会1. #如果给定地址在不这个实例化的IP地址范围内返会-1.  IP('192.168.1.0/24').overlaps('192.168.1.254') Out[131]: 1 IP('192.168.1.0/24').overlaps('192.168.2.254') Out[132]: 0 IP('192.168.1.0/24').overlaps('192.168.0.0/16') Out[134]: -1 ---------------------------------------- #实例化后的两个IP地址可以进行比较,IPv4总是小于IPv6地址,第一个地址总是小的。 掩码短的小于掩码长的 #如果self < other,返会-1, 如果self == other,返会0,如果self > other,返会1. ip Out[158]: IPint('192.168.1.0/24') ip2 Out[159]: IPint('1.1.1.1') ip3 Out[160]: IP('192.0.0.0/8') ipv6 Out[161]: IPint('2003::/64') ip4 = IP('192.168.1.0/24') ip.__cmp__(ip4) Out[163]: 0 ip.__cmp__(ip3) Out[166]: 1 ip.__cmp__(ipv6) Out[168]: -1 ip > ip2 Out[177]: True ip < ip2 Out[178]: False ip == i 

IP类,class IP(IPint):

IP类继承自IPint,所以IP类具有IPint的所有方法。

IP类主要处理IP地址和网络。IP类与IPint相比,返会的不再是整数型值,而是网络形式的字符串。

ipint = IPint('192.168.1.0/24') ip = IP('192.168.1.0/24') ipint.net() Out[197]:  ip.net() #返回网络地址 Out[198]: IP('192.168.1.0') ip.broadcast() #返会广播地址 Out[199]: IP('192.168.1.255') ipint.broadcast() Out[200]:  ip.netmask() #返会网络掩码 Out[201]: IP('255.255.255.0') ip.reverseName() Out[207]: '1.168.192.in-addr.arpa.' ip.reverseNames() #返会用于反向查找的列表值。 Out[208]: ['1.168.192.in-addr.arpa.'] IP('213.221.112.224/30').reverseNames() Out[209]: ['224.112.221.213.in-addr.arpa.', '225.112.221.213.in-addr.arpa.', '226.112.221.213.in-addr.arpa.', '227.112.221.213.in-addr.arpa.'] IP('::1:2').reverseNames() Out[211]: ['2.0.0.0.1.ip6.arpa.'] IP('213.221.112.224/30').reverseName() #返会用于反向查找的一个字符串,而不是列表。 Out[217]: '224-227.112.221.213.in-addr.arpa.' IP('10.1.1.1').make_net(24) #对于单个IP地址,可以加上掩码,返会新的IP地址实例 Out[231]: IP('10.1.1.0/24') ip Out[235]: IP('192.168.1.0/24') ip.__getitem__(1) #返回网络号中的地i个地址 Out[236]: IP('192.168.1.1') 

IPSet类,IPSet(collections.MutableSet):

可以用来对网段进行汇总。

IPSet仅仅接收IP实例的对象。

IPSet的值是存在列表中。

from IPy import IPSet from IPy import IP ipset = IPSet() #实例化一个IPSet对象 ipset.add(IP('192.168.1.0/24')) #给IPSet集合中添加一个网段 ipset Out[301]: IPSet([IP('192.168.1.0/24')]) ipset.add([IP('192.168.2.0/24'),IP('192.168.3.0/24')]) ipset #以列表形式添加多个网段 Out[303]: IPSet([IP('192.168.1.0/24'), IP('192.168.2.0/23')]) ipset.add(IP('192.168.0.0/16')) ipset#会对已有的所有网段进行汇总 Out[308]: IPSet([IP('192.168.0.0/16')]) ipset.discard(IP('192.168.1.0/24')) #移除汇总网段中某个网段 ipset Out[310]: IPSet([IP('192.168.0.0/24'), IP('192.168.2.0/23'), IP('192.168.4.0/22'), IP('192.168.8.0/21'), IP('192.168.16.0/20'), IP('192.168.32.0/19'), IP('192.168.64.0/18'), IP('192.168.128.0/17')]) n [317]: ipset2 = IPSet() ipset2.add(IP('192.168.1.0/24')) ipset2 Out[319]: IPSet([IP('192.168.1.0/24')]) ipset.isdisjoint(ipset2) #判断某个集合中的网段是否在现有集合网段中 Out[320]: True ipset3 = IPSet() ipset3.add(IP('192.168.2.0/24')) ipset.isdisjoint(ipset3) Out[323]: False ipset.__contains__(IP('192.168.2.0/24')) #判断某个网段是否在现有汇总网段中 Out[335]: True 

IPy中的其他常用方法:

def _parseAddressIPv6(ipstr): #将IPv6字符串解析为十进制的整型数据 ipv6 = IPy._parseAddressIPv6('1080:200C::1') ipv6 Out[345]: 42049 IP(ipv6) Out[346]: IP('1080:200c::1') def parseAddress(ipstr, ipversion=0):#解析IP地址 IPy.parseAddress('192.168.1.1') Out[348]: (, 4) IPy.parseAddress('123.132')#不够的后面加0补齐 Out[349]: (, 4) IPy.intToIp(, version=4) Out[351]: '192.168.1.1' def intToIp(ip, version): #将整型的IP地址转化为字符串IP地址 IPy.intToIp(, version=6) Out[352]: '0000:0000:0000:0000:0000:0000:c0a8:0101' def _intToBin(val): #将int型的地址转化为二进制 IPy._intToBin(13241) Out[360]: '001' 

利用IPy写的小程序:

批量分配指定掩码和分配个数的IPv4或者IPv6地址:

通过下面的程序,可以指定开始的一个IPv4或者IPv6地址,然后指定掩码,指定需要生成的网段个数,就可以通过程序批量分配地址。

地址输出格式,可以根据需要,灵活定义。

# -*- coding: utf-8 -*- """ Created on Sun Dec 1 21:51:11 2019 @author: cao """ import IPy def get_ip_list(begin_ip, count, netmask): ip_list = '' #用来存放生成的IP地址 begin_ip = IPy.IP(begin_ip) ip_list += str(begin_ip) + '\n' #将第一个地址放入ip_列表中 if begin_ip.version() == 4: for i in range(count): ip = IPy.IP(begin_ip) new_ip = IPy.IP(ip.ip + 2  (32 - netmask)) begin_ip = str(new_ip) ip_list += begin_ip + '\n' else: for i in range(count): ipv6 = IPy.IP(begin_ip) new_ipv6 = IPy.IP(ipv6.ip + 2  (128 - netmask)) begin_ip = str(new_ipv6) ip_list += begin_ip + '\n' return ip_list if __name__ == "__main__": ipv6_list = get_ip_list(begin_ip = '2002::', count=10, netmask=64) print('批量分配业务IPv6地址:') print('============================') print(ipv6_list) ipv6_list2 = get_ip_list(begin_ip = 'FD00:0:2e3f::', count=10, netmask=127) print('批量分配互联IPv6地址:') print('============================') print(ipv6_list2) ip_list = get_ip_list(begin_ip='192.168.1.0', count=10,netmask=24) print('批量分配业务IPv4地址:') print('============================') print(ip_list) ip_list2 = get_ip_list(begin_ip='192.168.2.0', count = 10, netmask=30) print('批量分配互联IPv4地:') print('============================') print(ip_list2) 

程序运行结果:

批量分配业务IPv6地址: ============================ 2002:: 2002:0:0:1:: 2002:0:0:2:: 2002:0:0:3:: 2002:0:0:4:: 2002:0:0:5:: 2002:0:0:6:: 2002:0:0:7:: 2002:0:0:8:: 2002:0:0:9:: 2002:0:0:a:: 批量分配互联IPv6地址: ============================ fd00:0:2e3f:: fd00:0:2e3f::2 fd00:0:2e3f::4 fd00:0:2e3f::6 fd00:0:2e3f::8 fd00:0:2e3f::a fd00:0:2e3f::c fd00:0:2e3f::e fd00:0:2e3f::10 fd00:0:2e3f::12 fd00:0:2e3f::14 批量分配业务IPv4地址: ============================ 192.168.1.0 192.168.2.0 192.168.3.0 192.168.4.0 192.168.5.0 192.168.6.0 192.168.7.0 192.168.8.0 192.168.9.0 192.168.10.0 192.168.11.0 批量分配互联IPv4地: ============================ 192.168.2.0 192.168.2.4 192.168.2.8 192.168.2.12 192.168.2.16 192.168.2.20 192.168.2.24 192.168.2.28 192.168.2.32 192.168.2.36 192.168.2.40 

可将批量生成的IP地址直接复制到Excel表格,或者文件中,用作后续批量生成网络设备配置等。

按固定格式批量分配掩码为64位的IPv6地址:

在网络规划中,需要给业务分配IPv6地址时,假设掩码都是64。同时需要给出IPv6对应的网关地址。

以下程序,给出一个开始的IPv6地址,然后指定count需要分配多少个地址。就会打印出指定数量的IPv6地址,同时给错每个地址对应的指定的网关地址。

# -*- coding: utf-8 -*- """ Created on Tue Nov 26 16:04:36 2019 @author: cao """ #批量计算业务网段,默认按掩码64位计算 import IPy #按冒号分割后,判断段是否满足4位,不是前面补零 #这个是为了分下来地址格式比较规整。可以不需要。 def add_0(tmp): if len(tmp) == 3: tmp = '0' + tmp elif len(tmp) == 2: tmp = '00' + tmp elif len(tmp) == 1: tmp = '000' + tmp else: pass return tmp #传入一个IPv6地址,进项每段0的填充 def ipv6_format(ipv6): tmp_ip = '' for i in ipv6.split(':'): if(len(i) == 0): continue if(i == '0'): tmp_ip += '0:' continue tmp_ip += add_0(i) + ':' return tmp_ip + ':' #获取业务网段IPv6对应的网关地址 def ipv6_GW(ipv6_list): ip_list_gw = '' for ip_net in ipv6_list.split('\n'): if(len(ip_net) == 0): break ip_list_gw += ip_net + 'FFFF\n' return ip_list_gw if __name__ == "__main__": begin_ip = 'FD00:0:0004:009B::' ipv6_count = 10 ipv6_list = begin_ip + '\n' #业务网段地址 ipv6_gw = '' #业务网段对应的网关 for i in range(ipv6_count): ipv6 = IPy.IP(begin_ip) new_ipv6 = str.upper(str(IPy.IP(ipv6.ip + 264))) begin_ip = ipv6_format(new_ipv6) ipv6_list += begin_ip + '\n' print(ipv6_list) ipv6_gw = ipv6_GW(ipv6_list) print(ipv6_gw) 

程序运行结果:

FD00:0:0004:009B:: FD00:0:0004:009C:: FD00:0:0004:009D:: FD00:0:0004:009E:: FD00:0:0004:009F:: FD00:0:0004:00A0:: FD00:0:0004:00A1:: FD00:0:0004:00A2:: FD00:0:0004:00A3:: FD00:0:0004:00A4:: FD00:0:0004:00A5:: FD00:0:0004:009B::FFFF FD00:0:0004:009C::FFFF FD00:0:0004:009D::FFFF FD00:0:0004:009E::FFFF FD00:0:0004:009F::FFFF FD00:0:0004:00A0::FFFF FD00:0:0004:00A1::FFFF FD00:0:0004:00A2::FFFF FD00:0:0004:00A3::FFFF FD00:0:0004:00A4::FFFF FD00:0:0004:00A5::FFFF 

得到想要地址后,可以直接复制到Excel表格中,或者直接写到文件中。用于后续批量生成配置。

至于输出的IPv6地址格式,或者IPv4地址格式,可以根据需要灵活控制。


参考资料:

https://pypi.org/project/IPy/

IPy源码: https://github.com/autocracy/python-ipy/

https://zhuanlan.zhihu.com/p/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/201827.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 上午8:31
下一篇 2026年3月20日 上午8:31


相关推荐

  • Nmap常用命令总结「建议收藏」

    Nmap常用命令总结「建议收藏」1.nmap-sT192.168.96.4//TCP连接扫描,不安全,慢2.nmap-sS192.168.96.4//SYN扫描,使用最频繁,安全,快3.nmap-Pn192.168.96.4//目标机禁用ping,绕过ping扫描4.nmap-sU192.168.96.4//UDP扫描,慢,可得到有价值的服务器程序5.nmap-sI僵…

    2022年5月27日
    43
  • 理解IaaS、SaaS、paas的含义及区别

    理解IaaS、SaaS、paas的含义及区别理解 IaaS SaaS paas 的含义及区别你一定听说过云计算中的三个 高大上 的你一定听说过云计算中的三个 高大上 的概念 IaaS PaaS 和 SaaS 这几个术语并不好理解 不过 如果你是个吃货 还喜欢披萨 这个问题就好解决了 好吧 其实你根本不是一个吃货 之所以自我标榜为吃货 其实是为了收获赞叹式的夸奖 吃货还这么瘦 好羡慕啊 或者 总得给伦家的微丰找个像样的理由 一个 吃货 是怎样

    2026年3月10日
    2
  • load average信息详解

    load average信息详解一、什么是loadaverage?linux系统中的Load对当前CPU工作量的度量(WikiPedia:thesystemloadisameasureoftheamountofworkthatacomputersystemisdoing)。也有简单的说是进程队列的长度。LoadAverage就是一段时间(1分钟、5分钟、15分钟)内平均L

    2022年7月17日
    20
  • Windows2016 NLB操作模式

    Windows2016 NLB操作模式Windows2016N 操作模式 WIndowsNLB 的操作模式分为单播模式与组播模式单播模式在该模式下 NLB 集群内的所有服务器的 MAC 都会被替换成一个集群 MAC 地址 他们通过此群集 MAC 地址来接收外部来的连接 WebFr

    2026年3月17日
    2
  • hashmap动态扩容死循环_HashMap扩容

    hashmap动态扩容死循环_HashMap扩容HashMap扩容死循环问题源码分析问题(jdk1.7)一、首先hashmap单线程正常扩容遍历每个数组,依次遍历每个数组的链表,根据头插法由原来的1,2,3变为了3,2,1二、hashmap多线程扩容死循环问题两个线程e1,e2此时线程一先执行,但线程二的指向发生改变,改为线程变换后的具体存储;初始的e2指向0号位的1,但经过线程一的变换指向了2号位的1了,next也发生改变线程二开始在线程一的基础存储,当next2指向空时。e.next=newTable[i],也就

    2026年2月6日
    5
  • QT断点调试[通俗易懂]

    QT断点调试[通俗易懂]这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML图表FLowchart流程图导出与导入导出导入欢迎使用Ma…

    2022年5月21日
    685

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号