Convert the "little endian" hex string to an IP address in Python

What's the best way to turn a string into this form into an IP address: "0200A8C0" . The "octets" present in the line are in the reverse order, that is, this example line should generate 192.168.0.2 .

+6
python endianness sockets ip-address
source share
4 answers

Network address management is provided by the socket module.

socket.inet_ntoa(packed_ip)

Convert a 32-bit packed IPv4 address (a four-character string) to its standard string representation with square dots (for example, '123.45.67.89). This is useful when talking to a program using the standard C library, and they need objects of type struct in_addr, which is type C for 32-bit binary data, which this function takes as an argument.

You can translate the hexadecimal string to packed ip using struct.pack() and the small end, unsigned long format.

 >>> import socket >>> import struct >>> addr_long = int("0200A8C0",16) >>> hex(addr_long) '0x200a8c0' >>> struct.pack("<L", addr_long) '\xc0\xa8\x00\x02' >>> socket.inet_ntoa(struct.pack("<L", addr_long)) '192.168.0.2' >>> 
+27
source share
 >>> s = "0200A8C0" >>> bytes = ["".join(x) for x in zip(*[iter(s)]*2)] >>> bytes ['02', '00', 'A8', 'C0'] >>> bytes = [int(x, 16) for x in bytes] >>> bytes [2, 0, 168, 192] >>> print ".".join(str(x) for x in reversed(bytes)) 192.168.0.2 

It is short and clear; wrap it in a function with error checking to suit your needs.


Convenient grouping functions:

 def group(iterable, n=2, missing=None, longest=True): """Group from a single iterable into groups of n. Derived from http://bugs.python.org/issue1643 """ if n < 1: raise ValueError("invalid n") args = (iter(iterable),) * n if longest: return itertools.izip_longest(*args, fillvalue=missing) else: return itertools.izip(*args) def group_some(iterable, n=2): """Group from a single iterable into groups of at most n.""" if n < 1: raise ValueError("invalid n") iterable = iter(iterable) while True: L = list(itertools.islice(iterable, n)) if L: yield L else: break 
+4
source share

You can do something like this:

 >>> s = '0200A8C0' >>> octets = [s[i:i+2] for i in range(0, len(s), 2)] >>> ip = [int(i, 16) for i in reversed(octets)] >>> ip_formatted = '.'.join(str(i) for i in ip) >>> print ip_formatted 192.168.0.2 

Octet splitting could probably be done more elegantly, but I can't come up with a simpler path from the head.

EDIT: Or in one line:

 >>> s = '0200A8C0' >>> print '.'.join(str(int(i, 16)) for i in reversed([s[i:i+2] for i in range(0, len(s), 2)])) 192.168.0.2 
+2
source share

My attempt:

 a = '0200A8C0' indices = range(0, 8, 2) data = [str(int(a[x:x+2], 16)) for x in indices] '.'.join(reversed(data)) 
0
source share

All Articles