views:

256

answers:

3

Using the standard Java libraries, what is the quickest way to get from the dotted string representation of an IPV4-address ("127.0.0.1") to the equivalent integer representation (2130706433).

And correspondingly, what is the quickest way to invert said operation - going from the integer 2130706433 to the string representation"127.0.0.1"?

+2  A: 

I've not tried it wrt. performance, but the simplest way is probably to use the NIO ByteBuffer.

e.g.

 byteBuffer.put(integer).array();

would return you a byte array representing the integer. You may need to modify the byte order.

Brian Agnew
why not just pick a byte order and make it the byte order of the ByteBuffer? Then you wouldn't have to worry about different default byte orders on different machines. EDIT: nevermind, the default is Big endian.
GregS
+2  A: 

I've modified my original answer. In Sun's implementation of InetAddress, the hashCode method produces the integer representation of the IPv4 address, but as the commenters correctly pointed out, this is not guaranteed by the JavaDoc. Therefore, I decided to use the ByteBuffer class to calculate the value of the IPv4 address instead.

import java.net.InetAddress;
import java.nio.ByteBuffer;

// ...

try {
    // Convert from integer to an IPv4 address
    InetAddress foo = InetAddress.getByName("2130706433");
    String address = foo.getHostAddress();
    System.out.println(address);

    // Convert from an IPv4 address to an integer
    InetAddress bar = InetAddress.getByName("127.0.0.1");
    int value = ByteBuffer.wrap(bar.getAddress()).getInt();
    System.out.println(value);

} catch (Exception e) {
    e.printStackTrace();
}

The output will be:

127.0.0.1
2130706433
William Brendel
Is the hashCode() well-defined as doing a 4-byte to int conversion ? If not, I suspect that's the case. An explanation is always good, mind.
Brian Agnew
The mapping from IP address to int needs to be a bijection. hashCode does not guarantee this.
GregS
This should be downvoted. Nothing in the Javadocs guarantees this behavior, it just happens to be the (sensible) Sun implementation at the moment. Sun could change this to just return a constant and it would still behave correctly, but your example would fail.
GregS
You're correct that InetAddress's hashCode() method does not specify how the hash is computed. I'll leave the answer here since it does "work" using the standard implementation of InetAddress.
William Brendel
I've updated my answer based on your concerns. My example now uses the ByteBuffer class to calculate the integer value of an IPv4 address instead of relying on InetAddress's hashCode method.
William Brendel
I've removed my downvote.
GregS
+4  A: 

String to int:

int pack(byte[] bytes) {
  int val = 0;
  for (int i = 0; i < bytes.length; i++) {
    val <<= 8;
    val |= bytes[i];
  }
  return val;
}

pack(InetAddress.getByName(dottedString).getAddress());

Int to string:

byte[] unpack(int bytes) {
  return new byte[] {
    (byte)((bytes >>> 24) & 0xff),
    (byte)((bytes >>> 16) & 0xff),
    (byte)((bytes >>>  8) & 0xff),
    (byte)((bytes       ) & 0xff)
  };
}


InetAddress.getByAddress(unpack(packedBytes)).getHostAddress()
Geoff Reedy
127.0.0.1 gives 2130706433, but 255.255.255.255 doesn't give 4294967295. signed vs. unsigned problem?
knorv
Geoff Reedy