• IPy模块。。ip范围求交集。。


    IP地址、网段的基本处理

    1. IPy模块包含IP类,使用它可以方便处理绝大部分格式为IPv6的网络和地址

      比如通过version方法来区分出IPv4和IPv6

      >>> import IPy
      >>> IPy.IP('10.0.0.0/8').version()
      4
      >>> IPy.IP('::1').version()
      6
    2. 通过指定的网段输出该网段的IP个数和所有的IP地址清单

      如下:

      $ more ip.py 
      #!/usr/bin/env python
      import IPy
      
      ip = IPy.IP('192.168.0.0/16')
      print ip.len()
      for x in ip:
          print x
    3. 反向解析名称、IP类型、IP转换等

      >>> ip = IP('192.168.1.20')
      >>> ip.reverseNames()               #反向解析地址格式
      ['20.1.168.192.in-addr.arpa.']
      >>> ip.iptype()                     #私网类型
      'PRIVATE'
      >>> IP('8.8.8.8').iptype()          #公网类型
      'PUBLIC'
      >>> IP('8.8.8.8').int()             #转换为整型格式
      134744072
      >>> IP('8.8.8.8').strHex()          #转换为十六进制格式
      '0x8080808'
      >>> IP('8.8.8.8').strBin()          #转换成二进制格式
      '00001000000010000000100000001000'
      >>> print IP('0x8080808')           #十六进制转换为IP格式
      8.8.8.8
      >>> print IP(134744072)             #整型格式转换为IP格式
      8.8.8.8
    4. IP方法也支持网络地址的转换,例如根据IP和掩码产生网段格式

      >>> print (IP('192.168.1.0').make_net('255.255.255.0'))
      192.168.1.0/24
      >>> print (IP('192.168.1.0/255.255.255.0',make_net=True))
      192.168.1.0/24
      >>> print (IP('192.168.1.0-192.168.1.255',make_net=True))
      192.168.1.0/24
    5. 通过strNormal方法指定不同wantprefixlen参数值以定制不同输出类型的网段,输出类型为字符串

      >>> IP('192.168.1.0/24').strNormal(0)   #无返回
      '192.168.1.0'
      >>> IP('192.168.1.0/24').strNormal(1)   #prefix格式
      '192.168.1.0/24'
      >>> IP('192.168.1.0/24').strNormal(2)   #decimalnetmask格式
      '192.168.1.0/255.255.255.0'
      >>> IP('192.168.1.0/24').strNormal(3)   #lastIP格式
      '192.168.1.0-192.168.1.255'

    多网络计算方法详解

    比较两个网段是否存在包含、重叠等关系,比如同网络但不同prefixlen会认为是不相等的网段,如10.0.0.0/16不等于10.0.0.0/24,另外即使具有相同的prefixlen但处于不同的网络地址,同样也视为不相等,如10.0.0.0/16不等于192.0.0.0/16。IPy支持类似于数值型数据的比较,以帮助IP对象进行比较。

    1. 比较IP大小

      >>> IP('10.0.0.0/24') < IP('12.0.0.0/24')
      True
    2. 判断IP地址和网段是否包含于另一个网段中

      >>> '192.168.1.100' in IP('192.168.1.0/24')
      True
      >>> IP('192.168.1.0/24') in IP('192.168.0.0/16')
      True
    3. 判断两个网段是否存在重叠(overlaps方法)

      >>> IP('192.168.0.0/23').overlaps('192.168.1.0/24')
      1
      >>> IP('192.168.1.0/24').overlaps('192.168.2.0/24')

    ipy模块简单运用:ip范围求交

      

    """
    # -*- coding: utf-8 -*-
    # @Author  : nanyu
    # @File    : 5.py
    # @Time    : 2018/12/24 15:50
    # @Software: PyCharm
    """
    # -*- coding: utf-8 -*-
    import IPy
    from IPy import IP
    import re
    # 获取掩码位的网络地址
    def IPy_IP_ByteMask(ip):
        try:
            ips = IPy.IP(ip)
            # 测试用
            if False:
                for ip in ips:
                    # print ip
                    if ip == ips[0]:
                        print 'network: ' + str(ips[0])
                    elif ip == ips[1]:
                        print 'first: ' + str(ips[1])
                    elif ip == ips[-1]:
                        print 'broad:' + str(ips[-1])
                    else:
                        pass
                        # print ip
            return ips
        except ValueError, e:
            # 利用报错机制,在报错时对最后一位数值进行减一操作,利用自我调用尝试到正确的网络位实现数据输出
            b = (ip.split('/')[0]).split('.')
            if int(b[3]):
                ip = b[0] + '.' + b[1] + '.' + b[2] + '.' + str(int(b[3])-1) + '/' + ip.split('/')[-1]
            elif int(b[2]):
                ip = b[0] + '.' + b[1] + '.' + str(int(b[2])-1) + '.0' + '/' + ip.split('/')[-1]
            elif int(b[1]):
                ip = b[0] + '.' + str(int(b[1]) - 1) + '.0.0' + '/' + ip.split('/')[-1]
            elif int(b[0]):
                ip = str(int(b[1]) - 1) + '.' + '.0.0.0' + '/' + ip.split('/')[-1]
            return IPy_IP_ByteMask(ip)
        except Exception, e:
            return None
    
    def ip_form(range):
        rl = [x for x in re.split(",| |
    |;", range)]
        ip = []
        for r in rl:
            if '/' in r:
                ip_mask = IPy_IP_ByteMask(r)
                ip_ran = IP(ip_mask)
                ip.append((ip_ran[0].int(), ip_ran[-1].int()))
            elif '-' in r:
                # 处理ip范围
                try:
                    ip_ran = IP(r)
                    ip.append((ip_ran[0].int(), ip_ran[-1].int()))
                except ValueError,e:
                    ip0 = IP(r[:r.index('-')]).int()
                    ip1 = IP(r[r.index('-') + 1:]).int()
                    ip.append((ip0,ip1))
            elif '*' in r and r !='*':
                ip_r = r.replace('*', '0')+'-'+ r.replace('*', '255')
                ip_ran = IP(ip_r)
                ip.append((ip_ran[0].int(), ip_ran[-1].int()))
            elif r == '*':
                ip_ran=IP('255.255.255.255')
                ip.append((0, ip_ran.int()))
            else:
                ip_ran = IP(r)
                ip.append(ip_ran.int())
        return ip
    
    def ip_range_intersection(range1, range2):
        ip1 = ip_form(range1)
        ip2 = ip_form(range2)
        inum = 0
        unnum = 0
        for i in ip1:
            for y in ip2:
                if type(i)== tuple and type(y)==tuple:
                    if i[0] > y[1] or i[1] < y[0]:
                        unnum+=1
                    else:
                        inum += 1
                if type(i) == tuple and type(y) == int:
                    if i[0] <= y <= i[1]:
                        inum += 1
                if type(i)== int and type(y) == tuple:
                    if y[0] <= i <= y[1]:
                        inum += 1
                else:
                    if i == y:
                        inum += 1
        if inum >= 1:
            return True
        else:
            return False
    if __name__ == '__main__':
    
        test = [
            [True, '20.22.20.22', '20.22.10.1-20.22.10.66'],
            [True, '20.22.20.22,20.22.10.231', '20.22.10.1-20.22.10,20.22.10.88-20.22.10.234'],
            [True, '20.22.10.1-20.22.10.5,20.22.10.10-20.22.10.52', '20.22.10.40-20.22.10.78'],
            [True, '20.22.10.1-20.22.10.66,20.22.10.50-20.22.10.90', '20.22.10.100,20.22.10.48/28'],
            [True, '20.22.20.22,20.22.10.231,20.22.10.72', '20.22.10.1,20.22.10.2,20.22.10.*'],
            [True, '20.22.20.22,20.22.10.231,20.22.10.72', '20.22.10.1,20.22.10.2,20.22.10.230/28'],
            [True, '20.22.20.22-20.22.10.66', '20.22.10.*'],
            [True, '1.1.1.1,10.10.10.10', '*'],
            [False, '20.22.20.22,20.22.10.231', '20.22.10.1-20.22.10.64,20.22.10.66-20.22.10.230,20.22.10.232-20.22.10.254'],
            [False, '20.22.20.22,20.22.10.231', '20.22.12.*'],
            [False, '20.22.20.22-20.22.40.231', '20.22.1.1-20.22.10.60,20.22.80.65'],
            [False, '20.22.20.22/20', '20.22.66.1/23']
        ]
    
        for t in test:
            try:
                print t
                ret = ip_range_intersection(t[1], t[2])
                assert ret == t[0], 
                    'ERROR: ip_range_intersection(%s, %s) return %s != %s' % (t[1], t[2], ret, t[0])
            except Exception, e:
                print repr(e)
                exit(0)
    
        print 'Success'
        
  • 相关阅读:
    android项目启动应用,卸载应用,分享
    android项目复杂的listview
    android项目获得手机里所有的应用程序
    android项目获取指定目录下可用空间
    android项目实现电话自动挂断的功能
    android项目浮窗的移动
    android项目双击或者多击的实现
    C#设计模式之工厂方法与简单工厂
    C#二分查找法与拉格朗日查找法
    C#快速排序算法
  • 原文地址:https://www.cnblogs.com/nanyu/p/9661044.html
Copyright © 2020-2023  润新知