Java - How to pack or unpack an unsigned integer from a byte array
Published
Updated
When dealing with sockets and streams, sometimes it is necessary to read packed or encoded bytes, shorts, floats, or integers which may be unsigned. The following examples will identify how to convert these unsigned values into a byte array or convert bytes into an unsigned value.
The following examples will produce results in the endianness of the system architecture that you are running it on. If your code is running on x86, this is most likely to be little-endian
. To ensure consistent ordering regardless of platform endianness, scroll down to my section on ByteBuffers.
Pack an unsigned integer
Convert an unsigned int 0 - 4,294,967,295 to a 4-byte packed array
/**
* @param data unsigned int (0 - 4,294,967,295)
* @return packed byte array [4]
*/
public static byte[] toBytes(final long data) {
return new byte[] {
(byte)((data >> 24) & 0xff),
(byte)((data >> 16) & 0xff),
(byte)((data >> 8) & 0xff),
(byte)((data >> 0) & 0xff),
};
}
Unpack an unsigned integer
Convert a 4-byte packed array to an unsigned integer
/**
* @param data (byte[4])
* @return unsigned int (0 - 4,294,967,295)
*/
public static long toUInt(final byte[] data) {
if (data == null || data.length != 4)
throw new IllegalArgumentException("!= 4 bytes");
return (long)(
(long)(data[3] & 0xffL) << 24 |
(long)(data[2] & 0xffL) << 16 |
(long)(data[1] & 0xffL) << 8 |
(long)(data[0] & 0xffL)
);
}
Pack an unsigned short
Convert an unsigned short 0 - 65,535 and return a 2-byte packed array.
/**
* @param unsigned short (0 - 65,535)
* @return (byte[2])
*/
public static byte[] toBytes(final int data) {
return new byte[] {
(byte)((data >> 24) & 0xff),
(byte)((data >> 16) & 0xff),
(byte)((data >> 8) & 0xff),
(byte)((data >> 0) & 0xff),
};
}
Unpack an unsigned short
Convert a 2-byte packed array to an unsigned short
/**
* @param data (byte[2])
* @return short (0 - 65,535)
*/
public static int toUShort(final byte[] data) {
if (data == null || data.length != 2)
throw new IllegalArgumentException("!= 2 bytes");
return (int)(
(int)(data[1] & 0xff) << 8 |
(int)(data[0] & 0xff)
);
}
Pack an unsigned byte
Convert an unsigned byte 0 - 255 and return a 1-byte packed array.
/**
* @param number unsigned byte (0-255)
* @return (byte[1])
*/
public static byte[] unsignedToBytes(final short number) {
return new byte[] { (byte) (number & 0xff) };
}
Unpack an unsigned byte
Convert a 1-byte packed array to an unsigned byte
/**
* @param data (byte[1])
* @return short (0-255)
*/
public static short toUByte(final byte[] data) {
if (data == null || data.length != 1)
throw new IllegalArgumentException("!= 1 byte");
return (short) (data[0] & 0xff);
}
Pack a float
Convert a float to a 4-byte array
public static byte[] toBytes(final float data) {
return toBytes(Float.floatToRawIntBits(data));
}
Pack a double
Convert a double to a 8-byte array
public static byte[] toBytes(final double data) {
return toBytes(Double.doubleToRawLongBits(data));
}
Packing unsigned integers using ByteBuffers
The following code will pack an unsigned integer using the big endian byte order. You can also replace ByteOrder.BIG_ENDIAN
with ByteOrder.LITTLE_ENDIAN
should you need it.
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
...
long data = 4294967295L;
byte[] bytes = ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt((int)data).array();