vote up 2 vote down star
1

Hi,

since Java doesn't provide a default way to do this,

what's a fast way to convert an Integer into a Byte Array?

e.g. 0xAABBCCDD => {AA, BB, CC, DD}

flag

Does it matter what format the resulting byte array is? What will you do with it? – skaffman 2 days ago

3 Answers

vote up 8 vote down check

Have a look at the ByteBuffer class.

ByteBuffer b = ByteBuffer.allocate(4);
//b.order(ByteOrder.BIG_ENDIAN); // optional, the initial order of a byte buffer is always BIG_ENDIAN.
b.putInt(0xAABBCCDD);

byte[] result = b.array();

Setting the byte order ensures that result[0] == 0xAA, result[1] == 0xBB, result[2] == 0xCC and result[3] == 0xDD.

Or alternatively, you could do it manually:

byte[] toBytes(int i)
{
  byte[] result = new byte[4];

  result[0] = (byte) (i >> 24);
  result[1] = (byte) (i >> 16);
  result[2] = (byte) (i >> 8);
  result[3] = (byte) (i /*>> 0*/);

  return result;
}

The ByteBuffer class was designed for such dirty hands tasks though. In fact the private java.nio.Bits defines these helper methods that are used by ByteBuffer.putInt():

private static byte int3(int x) { return (byte)(x >> 24); }
private static byte int2(int x) { return (byte)(x >> 16); }
private static byte int1(int x) { return (byte)(x >>  8); }
private static byte int0(int x) { return (byte)(x >>  0); }
link|flag
2  
this would work well if the bytebuffer is already there... otherwise it seems like it would take longer to do the allocation, than to just allocate a byte array of length 4 and do the shifting manually... but we're probably talking about small differences. – Jason S 2 days ago
2  
get it right first, then profile, then optimize ;) – Gregory Pakosz 2 days ago
The ByteBuffer instance can be cached; and internally it's surely implemented with shifting and masking anyway. – Gregory Pakosz 2 days ago
This is a perfectly fine answer. Note that big-endian is the specified default, and the methods are "chainable", and the position argument is optional, so it all reduces to: byte[] result = ByteBuffer.allocate(4).putInt(0xAABBCCDD).array(); Of course, if you're doing this repeatedly and concatenating all the results together (which is common when you're doing this kind of thing), allocate a single buffer and repeatedly putFoo() all the things into it that you need -- it will keep track of the offset as you go. It's really a tremendously useful class. – Kevin Bourrillion yesterday
@Kevin, thank you – Gregory Pakosz 23 hours ago
vote up 2 vote down

Using BigInteger:

private byte[] bigIntToByteArray( final int i ) {
    BigInteger bigInt = BigInteger.valueOf(i);      
    return bigInt.toByteArray();
}

Using DataOutputStream:

private byte[] intToByteArray ( final int i ) throws IOException {  	
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(bos);
    dos.writeInt(i);
    dos.flush();
    return bos.toByteArray();
}

Using ByteBuffer:

public byte[] intToBytes( final int i ) {
    ByteBuffer bb = ByteBuffer.allocate(4); 
    bb.putInt(i); 
    return bb.array();
}
link|flag
1  
pay attention to the byte order though – Gregory Pakosz 2 days ago
vote up 2 vote down

You can use BigInteger:

From Integers:

byte[] array = BigInteger.valueOf(0xAABBCCDD).toByteArray();
System.out.println(Arrays.toString(array))
// --> {-86, -69, -52, -35 }

The returned array is of the size that is needed to represent the number, so it could be of size 1, to represent 1 for example. However, the size cannot be more than four bytes if an int is passed.

From Strings:

BigInteger v = new BigInteger("AABBCCDD", 16);
byte[] array = v.toByteArray();

However, you will need to watch out, if the first byte is higher 0x7F (as is in this case), where BigInteger would insert a 0x00 byte to the beginning of the array. This is needed to distinguish between positive and negative values.

link|flag
thanks! But since this is BigInteger, will ints wrap around correctly? That is integers that are outside Integer.MAX_VALUE but can still be represented with only 4 bytes? – Buttercup 2 days ago
This is certainly not fast to execute. ;) – Peter Lawrey 2 days ago
This is not a good option. Not only it may add 0x00 byte, it may also strip leading zeros. – ZZ Coder 2 days ago

Your Answer

Get an OpenID
or

Not the answer you're looking for? Browse other questions tagged or ask your own question.