Converting between IPv4 addresses and 32-bit integers in Python

June 29, 2010

When you write code that deals with IPv4 addresses, every so often you wind up in situations where you want to convert addresses in conventional text form to unsigned 32-bit integers and manipulate them in various ways (and then convert the results back to normal notation). This is something I've been dealing with recently, so I've been working on this today.

Python doesn't have any standard library functions that directly do these conversions. You can write your own code for this (but it's just long enough to be annoying), or alternately you can glue together the socket and struct modules to get what you want.

socket.inet_aton doesn't directly convert an IP address to a 32-bit integer; instead it convert it to a 32-bit packed binary string. To get an actual integer, we need to unpack the string with struct.unpack. The one gotcha is that inet_aton returns results in network byte order, so if we want our IP addresses as natural numbers (in host byte order) we need to tell struct to do this conversion. To convert the other way we can use socket.inet_ntoa, which also has the same requirement of working in network byte order.

So we wind up with the following small and almost symmetric routines:

def ip_to_uint32(ip):
   t = socket.inet_aton(ip)
   return struct.unpack("!I", t)[0]

def uint32_to_ip(ipn):
   t = struct.pack("!I", ipn)
   return socket.inet_ntoa(t)

If you want your unsigned 32-bit integer IPv4 addresses in network byte order, leave out the ! in the unpack() and pack() format strings. Probably you don't, though, unless you are doing peculiar things with them.

(Given what this does, there is no point in using socket.inet_pton instead of inet_aton; we intrinsically deal only with IPv4 addresses anyways, so extra generality is actually counterproductive.)

PS: if you slap together code like this, it's a good idea to test it with simple IPv4 addresses that you can easily work out the numeric values for by hand. I almost skipped doing this and thus almost missed that inet_aton returns results in network byte order instead of host byte order. Such a mistake is entertaining, but only from a suitable distance.

Written on 29 June 2010.
« There is such a thing as too much SQL (a reminder to myself)
An update on comment spammer behavior here on WanderingThoughts »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Tue Jun 29 22:59:48 2010
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.