【问题标题】:How to compare IPV6 addresses in python如何在python中比较IPV6地址
【发布时间】:2014-06-07 09:49:25
【问题描述】:

我使用 python --version 2.6 和 Solaris 10 作为操作系统

这些是一些有效的 IPV6 地址。我将这些 IP 地址作为 string

  • 2001:cdba:0000:0000:0000:0000:3257:9652
  • 2001:cdba:0:0:0:0:3257:9652
  • 2001:cdba::3257:9652

我必须比较所有 ip 并检查它们是否表示相同的 ipv6 地址(表示为不同的符号)。我进行了很多搜索,找到了一些在 python 3 中可用的类,例如 ipaddress,但我不能使用它,因为我有 python 2.6 版本。python 2.6 中有可用的类吗?

谢谢

【问题讨论】:

  • 相同的 ipv6 什么?地区?子网?
  • 我必须比较所有相同但表示为不同符号的 ipv6 地址。
  • 这些“符号”是什么?帖子里只有这3个?拆分你的字符串并删除前导零,然后你就有了统一的表示。

标签: python compare ip-address


【解决方案1】:

我只会使用一些字符串操作,例如

def pad(addr):
    groups = addr.split(':')
    empty = None
    for i,g in enumerate(groups):
        if empty is None and len(g) == 0: empty = i
        elif len(g) < 4:
            groups[i] = '0'*(4-len(g))+g


    if empty is not None:
        groups=groups[:empty] + ['0000',]*(8-len(groups)+1) + groups[empty+1:]

    return ':'.join(groups)

if pad('2001:cdba:0000:0000:0000:0000:3257:9652') == pad('2001:cdba::3257:9652'):
    print('Same!')

【讨论】:

    【解决方案2】:

    你可以使用套接字。

    import socket
    ip1 = "2001:cdba:0000:0000:0000:0000:3257:9652"
    ip2 = "2001:cdba::3257:9652"
    if socket.inet_pton(socket.AF_INET6, ip1) == socket.inet_pton(socket.AF_INET6, ip2):
         print "match"
    

    【讨论】:

      【解决方案3】:

      你可以使用regex.sub:

      st_arr = ['2001:cdba:0000:0000:0000:0000:3257:9652', '2001:cdba:0:0:0:0:3257:9652', '2001:cdba::3257:9652']
      
      new_string_arr = [re.sub(r'[:]+', ':', re.sub(':[0]+', ':', st))) for st in st_arr]
      
      new_string_arr
      Out[63]: ['2001:cdba:3257:9652', '2001:cdba:3257:9652', '2001:cdba:3257:9652']
      
      new_string_arr[0] == new_string_arr[1] == new_string_arr[2]
      Out[64]: True
      

      首先,正则表达式将模式:[0]+ 替换为:,之后由于可能有多个冒号,我将模式[:]+ 替换为:

      【讨论】:

      • 它不适用于 aaaa:bbbb:cccc:dddd:eeee:ffff:1111:: 和 aaaa:bbbb:cccc:dddd:eeee:ffff:1111:0 符号
      • @user3717431:我已经更新了我的答案。现在可以了。
      • @AnkurAnkan 你的回答是,AFAICS,对待'2001:cdba:0000:0000:0000:0000:3257:9652''2001:cdba:0000:0000:0000:3257:0000:9652' 一样...
      • @user3717431 格式错误,只有“零的连续部分替换为双冒号 (::)”,将一个部分替换为值 0 是不正确的
      【解决方案4】:

      在比较 ipaddress 之前,您可以使用 socket lib 检查它们是否是有效的 ipv6 格式:

      import socket
      
      def is_valid_ipv6_address(address):
      try:
          socket.inet_pton(socket.AF_INET6, address)
      except socket.error:  # not a valid address
          return False
      return True
      

      验证后现在您可以使用正则表达式来比较它们是否相等迭代所有 ipv6 地址,:

      if(is_valid_ipv6_address(ipv6Address)):
          new_ipv6Address=re.sub(r'::[0]', '::',re.sub(r'[::]+', '::', re.sub(':[0]+:', '::', re.sub(':[0]+:', '::', ipv6Address))))
      

      这也适用于 aaaa:bbbb:cccc:dddd:eeee:ffff:1111:: 和 aaaa:bbbb:cccc:dddd:eeee:ffff:1111:0 格式。

      【讨论】:

      • 我认为检查它是否是有效的IP地址然后比较是个好选择...
      【解决方案5】:

      安装ipaddr

      import ipaddr
      
      s1="2001:cdba:0000:0000:0000:0000:3257:9652"
      ips=["2001:cdba:0:0:0:0:3257:9652","2001:cdba::3257:9652","2001:cdba:0000:0000:0000:0000:3257:9651"]
      
      results=[]
      
      
      for i in ips:
          print ipaddr.IPv6Address(i).exploded # re adds leading zeros etc..
          if ipaddr.IPv6Address(i).exploded==s1:
              results.append(i)
      print results
      
      2001:cdba:0000:0000:0000:0000:3257:9652  
      2001:cdba:0000:0000:0000:0000:3257:9652
      2001:cdba:0000:0000:0000:0000:3257:9651
      ['2001:cdba:0:0:0:0:3257:9652', '2001:cdba::3257:9652']
      

      【讨论】:

        猜你喜欢
        • 2017-07-20
        • 1970-01-01
        • 1970-01-01
        • 2013-05-13
        • 2012-02-08
        • 2018-09-23
        • 2012-12-04
        • 1970-01-01
        • 2010-12-31
        相关资源
        最近更新 更多