31

I have an int which contains an IP address in network byte order, which I would like to convert to an InetAddress object. I see that there is an InetAddress constructor that takes a byte[], is it necessary to convert the int to a byte[] first, or is there another way?

kdt
  • 27,905
  • 33
  • 92
  • 139
  • Can you post an example how this int look like and how its string representation should look like? I can't imagine how to put 255255255255 in an int, it would overflow. – BalusC Dec 24 '09 at 10:00
  • 2
    @BalusC: A IPv4 address is just a 32 bit number, it's just that it's usually represented as 4 8-bit values. The information fits just fine in 32 bits, though. – skaffman Dec 24 '09 at 10:03
  • 4
    Remember that, if you want to ever support IPv6, you can't use single int to handle IP addresses. – iny Dec 24 '09 at 10:08

10 Answers10

30

Tested and working:

int ip  = ... ;
String ipStr = 
  String.format("%d.%d.%d.%d",
         (ip & 0xff),   
         (ip >> 8 & 0xff),             
         (ip >> 16 & 0xff),    
         (ip >> 24 & 0xff));
Danny Beckett
  • 20,529
  • 24
  • 107
  • 134
hbr
  • 469
  • 1
  • 6
  • 7
  • 6
    This converts the bytes in the wrong order. It would work for little-endian ints, but the question asked about "network byte order" which is big-endian as are ints in Java. The correct order is: `String.format("%d.%d.%d.%d", (ip >> 24 & 0xff), (ip >> 16 & 0xff), (ip >> 8 & 0xff), (ip & 0xff));` – Mr. Kevin Thomas Nov 27 '17 at 22:55
17

This should work:

int ipAddress = ....
byte[] bytes = BigInteger.valueOf(ipAddress).toByteArray();
InetAddress address = InetAddress.getByAddress(bytes);

You might have to swap the order of the byte array, I can't figure out if the array will be generated in the correct order.

skaffman
  • 398,947
  • 96
  • 818
  • 769
  • 2
    That does indeed still require swapping the order of the byte array. However, it turns out my input was actually in host order after all! Thanks. – kdt Dec 24 '09 at 11:56
  • 15
    will not work for addresses in the range 0.0.0.0 - 0.127.255.255 and 255.128.0.0 - 255.255.255.255: `bytes` will have less than 4 elements – user85421 Jan 21 '10 at 16:31
  • @NikolayKuznetsov Because those ranges would result in a byte array of size 3 or less, whereas InetAddress requires the array to be of size 4 or 16. – aij Apr 02 '14 at 05:27
  • 3
    Dangerous. Does not work, for instance for 0.0.0.0. Not reliable! – toom Dec 09 '15 at 19:13
4

I think that this code is simpler:

static public byte[] toIPByteArray(int addr){
        return new byte[]{(byte)addr,(byte)(addr>>>8),(byte)(addr>>>16),(byte)(addr>>>24)};
    }

static public InetAddress toInetAddress(int addr){
    try {
        return InetAddress.getByAddress(toIPByteArray(addr));
    } catch (UnknownHostException e) {
        //should never happen
        return null;
    }
}
aalmeida
  • 339
  • 3
  • 5
  • 3
    This is almost right, but you got the order of the bytes backwards: http://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html#getByAddress(byte[]) – aij Apr 02 '14 at 06:03
4

If you're using Google's Guava libraries, InetAddresses.fromInteger does exactly what you want. Api docs are here

If you'd rather write your own conversion function, you can do something like what @aalmeida suggests, except be sure to put the bytes in the right order (most significant byte first).

aij
  • 5,903
  • 3
  • 37
  • 41
2
public static byte[] int32toBytes(int hex) {
    byte[] b = new byte[4];
    b[0] = (byte) ((hex & 0xFF000000) >> 24);
    b[1] = (byte) ((hex & 0x00FF0000) >> 16);
    b[2] = (byte) ((hex & 0x0000FF00) >> 8);
    b[3] = (byte) (hex & 0x000000FF);
    return b;

}

you can use this function to turn int to bytes;

bowman han
  • 1,097
  • 15
  • 25
1

Not enough reputation to comment on skaffman's answer so I'll add this as a separate answer.

The solution skaffman proposes is correct with one exception. BigInteger.toByteArray() returns a byte array which could have a leading sign bit.

byte[] bytes = bigInteger.toByteArray();

byte[] inetAddressBytes;

// Should be 4 (IPv4) or 16 (IPv6) bytes long
if (bytes.length == 5 || bytes.length == 17) {
    // Remove byte with most significant bit.
    inetAddressBytes = ArrayUtils.remove(bytes, 0);
} else {
    inetAddressBytes = bytes;
}

InetAddress address = InetAddress.getByAddress(inetAddressBytes);

PS above code uses ArrayUtils from Apache Commons Lang.

Dennis Laumen
  • 3,163
  • 2
  • 21
  • 24
  • 1
    I don't think an additional leading sign bit will be a problem, but missing bytes if the address is in the range 0.0.0.0 - 0.127.255.255 and 255.128.0.0 - 255.255.255.255 – user85421 Jan 21 '10 at 16:24
  • Sorry, I'm not an expert in this field. Could you elaborate on your comment? I'm afraid I'm missing the point (and could potentially have a bug in my code ;) ). – Dennis Laumen Jan 22 '10 at 12:03
  • @DennisLaumen You do. Try for example, 0, 42, or -42. You should get 0.0.0.0, 0.0.0.42, and 255.255.255.214. Instead you'll get an exception. See also https://en.wikipedia.org/wiki/Twos_complement – aij Apr 02 '14 at 05:45
1

Using Google Guava:

byte[] bytes =Ints.toByteArray(ipAddress);

InetAddress address = InetAddress.getByAddress(bytes);

0

Since comments cannot be formatted, let me post the code derived from the comment by @Mr.KevinThomas:

if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
    ipAddress = Integer.reverseBytes(ipAddress);
}
sReturn = String.format(Locale.US, "%d.%d.%d.%d", (ipAddress >> 24 & 0xff), (ipAddress >> 16 & 0xff), (ipAddress >> 8 & 0xff), (ipAddress & 0xff));

It has been tested on Android.

Hong
  • 17,643
  • 21
  • 81
  • 142
-1

This may work try


public static String intToIp(int i) {
        return ((i >> 24 ) & 0xFF) + "." +
               ((i >> 16 ) & 0xFF) + "." +
               ((i >>  8 ) & 0xFF) + "." +
               ( i        & 0xFF);
    }

valli
  • 5,797
  • 2
  • 19
  • 9
  • 3
    He was asking for int-to-bytearray, not int-to-string. Also your words "this may work try" makes me think that you just googled blind and copypasted random function? Why? – BalusC Dec 24 '09 at 10:14
-1
  public InetAddress intToInetAddress(Integer value) throws UnknownHostException
  {
    ByteBuffer buffer = ByteBuffer.allocate(32);
    buffer.putInt(value);
    buffer.position(0);
    byte[] bytes = new byte[4];
    buffer.get(bytes);
    return InetAddress.getByAddress(bytes);
  }