ipv6数字转换

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liaoyanyunde/article/details/82868132

1、ipv6转换为十进制数

IPv6的地址长度为128位,是IPv4地址长度的4倍。于是IPv4点分十进制格式不再适用,采用十六进制表示。IPv6有3种表示方法。
(1) 冒分十六进制表示法
  格式为X:X:X:X:X:X:X:X,其中每个X表示地址中的16位,以十六进制表示,例如:
  ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
  这种表示法中,每个X的前导0是可以省略的,例如:
  2001:0DB8:0000:0023:0008:0800:200C:417A→ 2001:DB8:0:23:8:800:200C:417A
(2) 0位压缩表示法
  在某些情况下,一个IPv6地址中问可能包含很长的一段0,可以把连续的一段0压缩为“::”。但为保证地址解析的唯一性,地址中”::”只能出现一次,例如:
  FF01:0:0:0:0:0:0:1101 → FF01::1101
  0:0:0:0:0:0:0:1 → ::1
  0:0:0:0:0:0:0:0 → ::
(3) 内嵌IPv4地址表示法
  为了实现IPv4-IPv6互通,IPv4地址会嵌入IPv6地址中,此时地址常表示为:X:X:X:X:X:X:d.d.d.d,前96b采用冒分十六进制表示,而最后32b地址则使用IPv4的点分十进制表示,例如::192.168.0.1与::FFFF:192.168.0.1就是两个典型的例子,注意在前96b中,压缩0位的方法依旧适用。

#将ipv6转换为十进制数
def ipv62dec(ipv6):
    if checkipv6(ipv6):
        compressIndex = ipv6.find('::')
        print("compressIndex:"+str(compressIndex))
        ipv4Index = ipv6.find('.')
        print("ipv4Index:"+str(ipv4Index))
        if compressIndex==-1 and ipv4Index==-1:
            return noCompressipv62dec(ipv6)
        elif compressIndex!=-1 and ipv4Index==-1:
            return compressipv62dec(ipv6)
        elif compressIndex==-1 and ipv4Index!=-1:
            ipv4,ipv6=ipv4v6Split(ipv6)
            if ipv4 and ipv6:
                return str(int(ipv42dec(ipv4))+int(noCompressipv62dec(ipv6)))
            else:
                return ""
        elif compressIndex != -1 and ipv4Index != -1:
            ipv4, ipv6 = ipv4v6Split(ipv6)
            if ipv4 and ipv6:
                return str(int(ipv42dec(ipv4))+int(compressipv62dec(ipv6)))
            else:
                return ""
        else:
            return ""
    else:
        return ""
#Ipv6每段不补齐0 形成完整的4位,如2001:DB8:0:23:8:800:200C:417A,补齐为2001:0DB8:0000:0023:0008:0800:200C:417A
def ipseg2str(ipseglist):
    ipstr=''
    for ipseg in ipseglist:
        if len(ipseg) == 1:
            ipseg = '000' + ipseg
        elif len(ipseg) == 2:
            ipseg = '00' + ipseg
        elif len(ipseg) == 3:
            ipseg = '0' + ipseg
        elif len(ipseg) == 4:
            ipseg = ipseg
        else:
            return ""
        ipstr += ipseg
    return ipstr
##没有0压缩的Ipv6转换为十进制,如2001:DB8:0:23:8:800:200C:417A
def noCompressipv62dec(ipv6):
    iplist = ipv6.split(":")
    if iplist:
        ipstr = ipseg2str(iplist)
        print(ipstr)
        return str(int(ipstr, 16))
    else:
        return ""
#带0压缩的ipv6转换为十进制,如FF01::1101
def compressipv62dec(ipv6):
    compressList = ipv6.split("::")
    print("compressList:" + str(compressList))
    ipstr = ""
    part1 = []
    part2 = []
    if len(compressList) == 2:
        part1 = compressList[0].split(":") if compressList[0] else []
        part2 = compressList[1].split(":") if compressList[1] else []
    if part1 or part2:
        ipstr += ipseg2str(part1)
        for i in range(8 - len(part1) - len(part2)):
            ipstr += '0000'
        ipstr += ipseg2str(part2)
        print("ipstr:" + ipstr)
        return str(int(ipstr, 16))
    else:
        return ""
#将内嵌ipv4的ipv6中的ipv6和ipv4分隔开,如FFFF::192.168.0.1  分隔为ipv4 192.168.0.1  ipv6 FFFF::0000:0000
def ipv4v6Split(ipv6):
    ipv4str = ''
    ipv6str = ''
    if checkipv6(ipv6):
        list = ipv6.split(":")
        if list:
            ipv4str = list[len(list) - 1]
            list.pop()
            ipv6str = ":".join(list) + ":0000:0000"
            print("ipv4:" + ipv4str)
            print("ipv6:" + ipv6str)
    return ipv4str,ipv6str
#校验ipv6的格式
def checkipv6(ipv6):
    matchobj = re.match(r'^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$',ipv6)
    if matchobj:
        return True
    else:
        return False

测试用例

class IPv6MethodsTest(unittest.TestCase):
    def test_ipv62dec(self):
        self.assertEqual(IPNumConvertMethods.ipv62dec('55555:5e:0:0:0:0:0:5668:eeee'),'')
        self.assertEqual(IPNumConvertMethods.ipv62dec('5555:5e:0:0:0:0:0:5668'), '113425732322140585886096426104944350824')
        self.assertEqual(IPNumConvertMethods.ipv62dec('5555:5e::5668'), '113425732322140585886096426104944350824')
        self.assertEqual(IPNumConvertMethods.ipv62dec('5555:5e::'), '113425732322140585886096426104944328704')
        self.assertEqual(IPNumConvertMethods.ipv62dec('::5555:5e'), '1431634014')
        self.assertEqual(IPNumConvertMethods.ipv62dec('2001:DB8:0:23:8:800:192.168.0.1'), '42540766411282593502542288130627076097')
        self.assertEqual(IPNumConvertMethods.ipv62dec('FFFF::192.168.0.1'), '340277174624079928635746076938671226881')
        self.assertEqual(IPNumConvertMethods.ipv62dec('::192.168.0.1'), '3232235521')
        self.assertEqual(IPNumConvertMethods.ipv62dec('::FFFF:192.168.0.1'), '281473913978881')

2、十进制转换为ipv6

#将ipv6中段中的0压缩,如005e 压缩为5e
def subZero(ipseg):
    index=0
    for i in range(len(ipseg)):
        if ipseg[i]=='0':
            index+=1
        else:
            break
    if index>=2:
        return ipseg[index:] if ipseg[index:] else '0'
    else:
        return ipseg
#将十进制数转换为ipv6
def dec2ipv6(dec):
    if checkdec(dec) and int(dec)<=340282366920938463463374607431768211455:
        hexstr=(hex(int(dec)))[2:]
        hexstrlen = len(hexstr)
        while hexstrlen<32:
            hexstr='0'+hexstr
            hexstrlen+=1
        result=subZero(hexstr[0:4])+":"+subZero(hexstr[4:8])+":"+subZero(hexstr[8:12])+":"+subZero(hexstr[12:16])+":"+subZero(hexstr[16:20])+":"+subZero(hexstr[20:24])+":"+subZero(hexstr[24:28])+":"+subZero(hexstr[28:])
        print("result:"+result)
        return result
    else:
        return ""
#校验十进制数字
def checkdec(dec):
    matchobj = re.match(r'(0[dD])?[0-9]+$',dec)
    if matchobj:
        return True
    else:
        return False

猜你喜欢

转载自blog.csdn.net/liaoyanyunde/article/details/82868132