我正在尝试从Python 2.7中的/proc/net/tcp6
读取 IPv6地址。以下是/proc/net/tcp6
中使用的IPv6表示示例:
00000000000000000000000000000000
00000000000000000000000001000000
0000000000000000FFFF00001F00C80A
我遇到的问题是将这些转换为“正确”的IPv6表示,如维基百科所述:
IPv6地址表示为八个十六进制组 数字,每组代表16位(两个八位字节)。这些团体是 用冒号(:)分隔。 IPv6地址的示例是:
2001:0db8:85a3:0000:0000:8a2e:0370:7334
[...]示例地址可以进一步简化:
2001:db8:85a3::8a2e:370:7334
在socket.inet_ntop
和struct.pack
的帮助下,这似乎最容易实现。
但是,我不知道要采用哪些步骤来生成这两个函数所需的特定格式。
使用Python 2.7 stdlib中的其他方法的任何其他方法当然都是受欢迎的。
为了便于比较,以下是我现在对从/proc/net/tcp
读取的 IPv4地址的做法:
>>> addr = '0101007F'
>>> addr = int(addr, 16)
>>> addr = struct.pack('<I', addr)
>>> addr = socket.inet_ntoa(addr)
>>> print addr
127.0.1.1
不幸的是inet_ntoa
不支持IPv6地址,您必须使用inet_ntop(AF_INET6, packed_ipv6)
。
但是我不知道如何使用in6_addr
函数将上述字符串转换为struct.pack
结构。
答案 0 :(得分:1)
这是一种有效的方法,并自动处理本机字节序:
def ipv6(addr):
addr = addr.decode('hex')
addr = struct.unpack('>IIII', addr)
addr = struct.pack('@IIII', *addr)
addr = socket.inet_ntop(socket.AF_INET6, addr)
return addr
样品:
>>> ipv6('00000000000000000000000001000000')
'::1'
>>> ipv6('B80D01200000000067452301EFCDAB89')
'2001:db8::123:4567:89ab:cdef'
步骤:
decode('hex')
),>IIII
),@IIII
),socket.inet_ntop
,最终生成正确的IPv6表示在systems that use little endian上,字节字符串将从DCBA-HGFE-LKJI-PONM
转换为ABCD-EFGH-IJKL-MNOP
。请参阅struct
模块&#39; byte order notation。
unpack
&amp;的替代方案pack
部分,但在我的系统上慢两倍,并且它不会自动处理本机字节序(假设这里有小端):
addr = ''.join(addr[i:i+4][::-1] for i in range(0, 16, 4))
答案 1 :(得分:0)
这样的东西?
from ipaddress import ip_address
components = [line[i:i+4] for i in range(0, len(line), 4)]
ipv6_string = ":".join(components)
print(ip_address(ipv6_string))