Wednesday, December 23, 2009

Managing IP addresses as integers

I was recently involved in a discussion about IP addresses and discovered that not everyone understands an IP address. I was told that an IP address is not an integer. Well, it is an integer, a 32-bit integer, but it is rarely represented as such. It is usually represented as four octets joined together with periods.

This is what most people know as an IP address: 127.0.0.1 and if I showed you the value 2130706433 you probably wouldn't recognize it as the same IP address.

I blogged some extension methods in Converting a string IP to and int and back that will help you if you need to convert an IP between the two formats using C#. The code is fairly obvious and easily ported to other languages.

The question often asked is why do you need to convert it?

The answer is speed and space.

Most often, when you receive an IP address it is in the string notation. Storing it in this notation inefficient because it takes between 7 (0.0.0.0) and 15 (255.255.255.255) bytes to store each address. Compare this to storing it as an Int32 which takes 4 bytes each time. A space saving of between 42% and 73%.

My advice is to convert it into an Int32 as soon as you receive it and then work with it as such from there onwards. Working with an IP as an Int32 will be faster because sorting and comparing Int32's will outstrip the same when using strings. Setting up an index against an Int32 column in a database will also be faster and smaller than doing the same against a varchar column.

When you need to show an integer IP to a user you'll need to convert it back to its string notation. This is easily done with the extension methods linked above.

The only draw back to using this approach for managing IP addresses is when you list IP's directly from your database. If they were stored as strings they'd be easy to recognize but listed as integers they're pretty useless.

2 comments:

  1. To comment on your 'direct from a database' reference. Most databases have built in functions to handle the conversion for you if you don't want to perform the calculation in code:
    MySQL's INET_ATON() and INET_NTOA(): dev.mysql.com/.../miscellaneous-f
    MS SQL doesn't seem to bundle a built in function: stackoverflow.com/.../what-is-the-mss

    ReplyDelete
  2. I was aware of the MySQL built in function and I've written the same function that can be called from MS SQL and I've event used the MySQL naming conventions in the MS SQL plugin functions that I created.
    However, I rarely use this functionality because most of the time I want to work with the IP as an int in the business layer and not a string. If I ever need to do a lookup or comparison in the BL then I'll want to do this with integers and not strings.
    So the times that they get converted to and from strings and ints is on immediate receipt of the IP from the OS and just before presentation on the UI.

    ReplyDelete