ChatGPT解决这个技术问题 Extra ChatGPT

Convert integer into byte array (Java)

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

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

Does it matter what format the resulting byte array is? What will you do with it?

R
RaphMclee

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); }

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.
The ByteBuffer instance can be cached; and internally it's surely implemented with shifting and masking anyway.
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.
If you plan on using that ByteBuffer in subsequent NIO writing operations, you will need to rewind it. Otherwise, you won't write anything! (Been there, done that!)
For who doesn't know. The putInt will always write 4 bytes, no matter what size the input integer is. If you only want 2 bytes, use putShort, etc ...
P
Pascal Thivent

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();
}

pay attention to the byte order though
Does ByteBuffer gives out an unsigned int?
@Pascal Using ByteBuffer I tried with ByteBuffer bb = ByteBuffer.allocate(3); For this it is giving java.nio.BufferOverflowException, I am not getting why it is not working for value less than 4? Can you please explain?
@SanjayJain You get a buffer overflow exception because ints in Java are 32-bits or 4 bytes in size, and therefore require you to allocate at least 4 bytes of memory in your ByteBuffer.
@GregoryPakosz is right about byte order. His answer using ByteBuffer is more intuitive if you are dealing with an int greater than 2^31 - 1.
M
Muskovets

use this function it works for me

public byte[] toByteArray(int value) {
    return new byte[] {
            (byte)(value >> 24),
            (byte)(value >> 16),
            (byte)(value >> 8),
            (byte)value};
}

it translates the int into a byte value


It's also worth nothing that this will work regardless of the most significant bit and more efficient compared to the other answers. Also could use '>>'.
A direct solution like this is certainly faster than calling any library method. Sometimes you just have to fiddle with the the bits directly with a few lines of code rather than incurring all the extra overhead of library method calls.
And this converts between languages well so is good for multi language software development.
P
Pang

If you like Guava, you may use its Ints class:

For intbyte[], use toByteArray():

byte[] byteArray = Ints.toByteArray(0xAABBCCDD);

Result is {0xAA, 0xBB, 0xCC, 0xDD}.

Its reverse is fromByteArray() or fromBytes():

int intValue = Ints.fromByteArray(new byte[]{(byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD});
int intValue = Ints.fromBytes((byte) 0xAA, (byte) 0xBB, (byte) 0xCC, (byte) 0xDD);

Result is 0xAABBCCDD.


n
notnoop

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.


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?
This is certainly not fast to execute. ;)
This is not a good option. Not only it may add 0x00 byte, it may also strip leading zeros.
M
Matt

Can also shift -

byte[] ba = new byte[4];
int val = Integer.MAX_VALUE;

for(byte i=0;i<4;i++)
    ba[i] = (byte)(val >> i*8);
    //ba[3-i] = (byte)(val >> i*8); //Big-endian

C
Community

Here's a method that should do the job just right.

public byte[] toByteArray(int value)
{
    final byte[] destination = new byte[Integer.BYTES];
    for(int index = Integer.BYTES - 1; index >= 0; index--)
    {
        destination[i] = (byte) value;
        value = value >> 8;
    };
    return destination;
};

h
helmy

Simple solution which properly handles ByteOrder:

ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()).putInt(yourInt).array();


M
Mukesh Bambhaniya

very easy with android

int i=10000;
byte b1=(byte)Color.alpha(i);
byte b2=(byte)Color.red(i);
byte b3=(byte)Color.green(i);
byte b4=(byte)Color.blue(i);

r
recnac

This will help you.

import java.nio.ByteBuffer;
import java.util.Arrays;

public class MyClass
{
    public static void main(String args[]) {
        byte [] hbhbytes = ByteBuffer.allocate(4).putInt(16666666).array();

        System.out.println(Arrays.toString(hbhbytes));
    }
}

M
Muskovets

It's my solution:

public void getBytes(int val) {
    byte[] bytes = new byte[Integer.BYTES];
    for (int i = 0;i < bytes.length; i ++) {
        int j = val % Byte.MAX_VALUE;
        bytes[i] = (j == 0 ? Byte.MAX_VALUE : j);
    }
}

Also Stringy method:

public void getBytes(int val) {
    String hex = Integer.toHexString(val);
    byte[] val = new byte[hex.length()/2]; // because byte is 2 hex chars
    for (int i = 0; i < hex.length(); i+=2)
        val[i] = Byte.parseByte("0x" + hex.substring(i, i+2), 16);
    return val;
}