ipv6數字轉換
阿新 • • 發佈:2018-11-05
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