i have a little problem with my script, where i need to convert ip in form \'xxx.xxx.xxx.xxx\' to integer representation and go back from this form.
def ipto
Python 3 has ipaddress module which features very simple conversion:
int(ipaddress.IPv4Address("192.168.0.1"))
str(ipaddress.IPv4Address(3232235521))
Below are the fastest and most straightforward (to the best of my knowledge) convertors for IPv4 and IPv6:
try:
_str = socket.inet_pton(socket.AF_INET, val)
except socket.error:
raise ValueError
return struct.unpack('!I', _str)[0]
-------------------------------------------------
return socket.inet_ntop(socket.AF_INET, struct.pack('!I', n))
-------------------------------------------------
try:
_str = socket.inet_pton(socket.AF_INET6, val)
except socket.error:
raise ValueError
a, b = struct.unpack('!2Q', _str)
return (a << 64) | b
-------------------------------------------------
a = n >> 64
b = n & ((1 << 64) - 1)
return socket.inet_ntop(socket.AF_INET6, struct.pack('!2Q', a, b))
Python code not using inet_ntop()
and struct
module is like order of magnitude slower than this regardless of what it is doing.
One line
reduce(lambda out, x: (out << 8) + int(x), '127.0.0.1'.split('.'), 0)
#!/usr/bin/env python
import socket
import struct
def ip2int(addr):
return struct.unpack("!I", socket.inet_aton(addr))[0]
def int2ip(addr):
return socket.inet_ntoa(struct.pack("!I", addr))
print(int2ip(0xc0a80164)) # 192.168.1.100
print(ip2int('10.0.0.1')) # 167772161
You lose the left-zero-padding which breaks decoding of your string.
Here's a working function:
def inttoip(ip):
return socket.inet_ntoa(hex(ip)[2:].zfill(8).decode('hex'))