99

I have an 8 byte array and I want to convert it to its corresponding numeric value.

e.g.

byte[] by = new byte[8];  // the byte array is stored in 'by'

// CONVERSION OPERATION
// return the numeric value

I want a method that will perform the above conversion operation.

Mnementh
  • 50,487
  • 48
  • 148
  • 202
pirate
  • 1,583
  • 3
  • 14
  • 12
  • 5
    What do you mean by "numeric value"? Do the bytes represent an integer (long) or floating point number (double) in binary? Are they the string representation of a number? Or yet another representation? – starblue Jun 22 '09 at 13:08
  • 1
    This was helpful: http://stackoverflow.com/questions/5399798/byte-array-and-int-conversion-in-java – TacB0sS Jun 03 '12 at 13:29
  • NB: TacB0sS' link was what I was actually looking for- both forwards and backwards conversion. – Jay Taylor Aug 01 '12 at 23:48
  • `new BigInteger(by).longValue()` – user207421 Jun 07 '19 at 04:23

9 Answers9

124

One could use the Buffers that are provided as part of the java.nio package to perform the conversion.

Here, the source byte[] array has a of length 8, which is the size that corresponds with a long value.

First, the byte[] array is wrapped in a ByteBuffer, and then the ByteBuffer.getLong method is called to obtain the long value:

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 0, 0, 0, 0, 4});
long l = bb.getLong();

System.out.println(l);

Result

4

I'd like to thank dfa for pointing out the ByteBuffer.getLong method in the comments.


Although it may not be applicable in this situation, the beauty of the Buffers come with looking at an array with multiple values.

For example, if we had a 8 byte array, and we wanted to view it as two int values, we could wrap the byte[] array in an ByteBuffer, which is viewed as a IntBuffer and obtain the values by IntBuffer.get:

ByteBuffer bb = ByteBuffer.wrap(new byte[] {0, 0, 0, 1, 0, 0, 0, 4});
IntBuffer ib = bb.asIntBuffer();
int i0 = ib.get(0);
int i1 = ib.get(1);

System.out.println(i0);
System.out.println(i1);

Result:

1
4
coobird
  • 159,216
  • 35
  • 211
  • 226
  • what about ByteBuffer.wrap(new byte[] {0, 0, 0, 1, 0, 0, 0, 4}).getLong()? this method should read next 8 byte and convert them to a long – dfa Jun 22 '09 at 12:56
114

Assuming the first byte is the least significant byte:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value += ((long) by[i] & 0xffL) << (8 * i);
}

Is the first byte the most significant, then it is a little bit different:

long value = 0;
for (int i = 0; i < by.length; i++)
{
   value = (value << 8) + (by[i] & 0xff);
}

Replace long with BigInteger, if you have more than 8 bytes.

Thanks to Aaron Digulla for the correction of my errors.

Mnementh
  • 50,487
  • 48
  • 148
  • 202
  • 8
    -1 bytes are signed values! And replace pow() with shift (<<)! "value = (value << 8) + (by[i] & 0xff)" – Aaron Digulla Jun 22 '09 at 12:39
  • Does the shift operator(<<) has right to left precedence? How does above code works? Its working all fine for me. Just wanna know the working. Thanx in advance – suraj Mar 10 '12 at 13:53
  • @Mnementh : Does the shift operator(<<) has right to left precedence? How does above code works? Its working all fine for me. Just wanna know the working. Thanx in advance – suraj Mar 10 '12 at 14:09
  • 5
    In case anyone else has the same issue I did, in the first example, by[i] must be cast to a long, otherwise it only works for values less than 2^32. That is, `value += ((long)by[i] & 0xffL) << (8 * i);` – Luke Apr 08 '12 at 03:25
17

If this is an 8-bytes numeric value, you can try:

BigInteger n = new BigInteger(byteArray);

If this is an UTF-8 character buffer, then you can try:

BigInteger n = new BigInteger(new String(byteArray, "UTF-8"));
Vincent Robert
  • 35,564
  • 14
  • 82
  • 119
  • I would've voted for this answer if it ended right after the first code snippet, or if it included some code to convert the string into a "numeric value". As-is, the second half of your answer seems like a non sequitur. – Laurence Gonsalves Jun 22 '09 at 12:26
  • Not what I meant in the first place, I changed my answer – Vincent Robert Jun 22 '09 at 12:32
17

Simply, you could use or refer to guava lib provided by google, which offers utiliy methods for conversion between long and byte array. My client code:

    long content = 212000607777l;
    byte[] numberByte = Longs.toByteArray(content);
    logger.info(Longs.fromByteArray(numberByte));
Chen Yi
  • 171
  • 1
  • 6
9

You can also use BigInteger for variable length bytes. You can convert it to Long, Integer or Short, whichever suits your needs.

new BigInteger(bytes).intValue();

or to denote polarity:

new BigInteger(1, bytes).intValue();
Jamel Toms
  • 4,525
  • 2
  • 27
  • 26
3

Complete java converter code for all primitive types to/from arrays http://www.daniweb.com/code/snippet216874.html

iBog
  • 2,245
  • 1
  • 20
  • 15
1

Each cell in the array is treated as unsigned int:

private int unsignedIntFromByteArray(byte[] bytes) {
int res = 0;
if (bytes == null)
    return res;


for (int i=0;i<bytes.length;i++){
    res = res | ((bytes[i] & 0xff) << i*8);
}
return res;
}
Asaf Pinhassi
  • 15,177
  • 12
  • 106
  • 130
  • Just a note that I needed to use 0xFFL, otherwise the cast from int 0xFF to long had a whole lot of incorrect 1 bits set when I printed Long.toHexString(l). – Luke Sep 24 '15 at 16:05
  • You need to use 0xFFL otherwise you get sign extension. – Gray May 23 '19 at 23:14
0
public static long byteArrayToLong(byte[] bytes) {
    return ((long) (bytes[0]) << 56)
            + (((long) bytes[1] & 0xFF) << 48)
            + ((long) (bytes[2] & 0xFF) << 40)
            + ((long) (bytes[3] & 0xFF) << 32)
            + ((long) (bytes[4] & 0xFF) << 24)
            + ((bytes[5] & 0xFF) << 16)
            + ((bytes[6] & 0xFF) << 8)
            + (bytes[7] & 0xFF);
}

convert bytes array (long is 8 bytes) to long

Serg
  • 1
0

You can try use the code from this answer: https://stackoverflow.com/a/68393576/7918717

It parses bytes as a signed number of arbitrary length. A few examples:

bytesToSignedNumber(false, 0xF1, 0x01, 0x04) returns 15794436 (3 bytes as int)

bytesToSignedNumber(false, 0xF1, 0x01, 0x01, 0x04) returns -251592444 (4 bytes as int)

bytesToSignedNumber(false, 0xF1, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04) returns -1080581331768770303 (8 of 9 bytes as long)

antaki93
  • 704
  • 7
  • 10