How to Convert Long to Byte[] and Back in Java

How do I convert Long to byte[] and back in java

public byte[] longToBytes(long x) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.putLong(x);
return buffer.array();
}

public long bytesToLong(byte[] bytes) {
ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
buffer.put(bytes);
buffer.flip();//need flip
return buffer.getLong();
}

Or wrapped in a class to avoid repeatedly creating ByteBuffers:

public class ByteUtils {
private static ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);

public static byte[] longToBytes(long x) {
buffer.putLong(0, x);
return buffer.array();
}

public static long bytesToLong(byte[] bytes) {
buffer.put(bytes, 0, bytes.length);
buffer.flip();//need flip
return buffer.getLong();
}
}

Since this is getting so popular, I just want to mention that I think you're better off using a library like Guava in the vast majority of cases. And if you have some strange opposition to libraries, you should probably consider this answer first for native java solutions. I think the main thing my answer really has going for it is that you don't have to worry about the endian-ness of the system yourself.

how to convert long to byte array in java?

The problem is the fact that you cast to byte too early:

tm_stp[0] = (byte) ((byte) ts>>24);
tm_stp[1] = (byte) ((byte) ts>>16);
tm_stp[2] = (byte) ((byte) ts>>8);
//^^^^

This causes the ts value to be truncated, replacing the first 24 bytes with 0s. After that, shifting by anything greater than or equal to 8 will return 0. To avoid incorrect behaviour with negative values, you should also use a bitmask. The correct code should look like this:

tm_stp[0] = (byte) ((ts >> 24) & 0xFF);
tm_stp[1] = (byte) ((ts >> 16) & 0xFF);
tm_stp[2] = (byte) ((ts >> 8) & 0xFF);
tm_stp[3] = (byte) ((ts >> 0) & 0xFF); // >> 0 not actually required, only for symmetry

Convert long to byte array and add it to another array

There are multiple ways to do it:

  • Use a ByteBuffer (best option - concise and easy to read):

    byte[] bytes = ByteBuffer.allocate(Long.SIZE / Byte.SIZE).putLong(someLong).array();
  • You can also use DataOutputStream (more verbose):

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(baos);
    dos.writeLong(someLong);
    dos.close();
    byte[] longBytes = baos.toByteArray();
  • Finally, you can do this manually (taken from the LongSerializer in Hector's code) (harder to read):

    byte[] b = new byte[8];
    for (int i = 0; i < size; ++i) {
    b[i] = (byte) (l >> (size - i - 1 << 3));
    }

Then you can append these bytes to your existing array by a simple loop:

// change this, if you want your long to start from 
// a different position in the array
int start = 0;
for (int i = 0; i < longBytes.length; i ++) {
bytes[start + i] = longBytes[i];
}

Long to Byte Conversion

Java's types are signed, bytes allow numbers between −128 and +127.this is the reason you were getting −34 for 222 value

     long a=121;
byte b=(byte)(a );
System.out.println("the value of b is" +b);

Java Converting long to bytes - which approach is more efficient

I suggest you look at how the Java code does it.

public final void writeLong(long v) throws IOException {
writeBuffer[0] = (byte)(v >>> 56);
writeBuffer[1] = (byte)(v >>> 48);
writeBuffer[2] = (byte)(v >>> 40);
writeBuffer[3] = (byte)(v >>> 32);
writeBuffer[4] = (byte)(v >>> 24);
writeBuffer[5] = (byte)(v >>> 16);
writeBuffer[6] = (byte)(v >>> 8);
writeBuffer[7] = (byte)(v >>> 0);
out.write(writeBuffer, 0, 8);
incCount(8);
}

as you can see, without a loop you have less operation.

The fastest way is to not do this at all and instead using Unsafe.writeLong() as this take a long and places it directly into memory instead of breaking it into bytes. This can be more than 10x faster.

How to convert a long into printable bytes

Java can handle a radix as high as 36 using the digits 0 - 9 and lower case letters a - z.

> Long.toString(12345678901L, 36)
"5o6aqt1"

> Long.parseLong("5o6aqt1", 36)
12345678901

You could create your own encoding using 65 of the 66 unreserved URI Characters (so your URI would not need escaping). The '-' sign needs to be used for negative numbers:

> Long65.toString(12345678901L)
"aFDIbA"

> Long65.parseLong65("aFDIbA")
12345678901

Here is the code for Long65()

import java.math.BigInteger;

public class Long65 {
private static int base = 65;
private static String URIchars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_.~";

public static String toString(Long aNumber) {
StringBuilder result = new StringBuilder();
if (aNumber < 0) {
result.append('-');
aNumber = -aNumber;
}
int r = (int)(aNumber % base);
if (aNumber - r == 0)
result.append(URIchars.charAt(r));
else
result.append(Long65.toString((aNumber - r) / base) + URIchars.charAt(r));
return result.toString();
}

public static long parseLong65(String aNumber) {
char[] digits;
int sign = 1;
if (aNumber.charAt(0) == '-') {
sign = -1;
digits = aNumber.substring(1).toCharArray();
} else {
digits = aNumber.toCharArray();
}
BigInteger bigBase = BigInteger.valueOf(base);
BigInteger power = bigBase.pow(digits.length);
BigInteger total = BigInteger.valueOf(0);
for (char digit : digits){
power = power.divide(bigBase);
total = total.add(power.multiply(BigInteger.valueOf(URIchars.indexOf(digit))));
}
return sign * total.longValue();
}
}


Related Topics



Leave a reply



Submit