Basic tech stuff

Programming and Linux administration

32 bit IP address to dotted notation in Ruby

Posted by Daniel Brahneborg on 2007 April 13

In one of our applications we store an IP address as a 32 bit integer. To show the value of this field it must be converted to normal dotted notation, and then back again to an integer to get stored in the database.

Going from dotted notation is easy:

require 'ipaddr'
IPAddr.new('1.2.3.4').to_i

Or, the “manual” version:

'1.2.3.4'.split('.').inject(0) {|total,value| (total << 8 ) + value.to_i}

I couldn’t find any examples of going from an integer to dotted notation, so I ended up with this:

address = 0x01020304
[24, 16, 8, 0].collect {|b| (address >> b) & 255}.join('.')

Andra bloggar om: , .

Advertisements

7 Responses to “32 bit IP address to dotted notation in Ruby”

  1. r said

    You can convert a decimal ip address to an IPAddr to dotted decimal using the following code:


    IPAddr.new(16909060, Socket::AF_INET).to_s

  2. Oh, thanks! That looked a bit cleaner, to say the least.

  3. Your manual version is twice as fast as using ipaddr in my tests over 4.2 million addresses. I’m going to wrap the manual version that you wrote in a method and avoid the apparent overhead of ipaddr.

    require 'ipaddr'
    
    A = 0
    B = 4294967
    
    def test_a
      (A..B).collect {|i| IPAddr.new(i, Socket::AF_INET).to_s }
    end
    
    def test_b
      (A..B).collect do |i|
        [24,16,8,0].collect {|b| (i >> b) & 255}.join '.'
      end
    end
    
    if ARGV[0] == 'a'
      test_a
    elsif ARGV[0] == 'b'
      test_b
    end
    
    $ for f in a b; do time ruby ip_as_int.rb $f; done
    
    real    2m20.408s
    user    2m7.500s
    sys     0m12.140s
    
    real    1m0.558s
    user    0m55.270s
    sys     0m4.950s
    
  4. Peter Marreck said

    While doing it manually is twice as fast as using IPAddr, I’m guessing that it will be way easier to upgrade the code when IPv6 becomes common.

  5. Yes, for IPv6 addresses, it won’t be worth doing it manually.

  6. milli said

    [address].pack(‘N’).unpack(‘C4’).join(‘.’)

  7. Oh, nice! Thanks!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: