How to Convert a Byte Array to a Hex String in Java?
I Have a Byte Array Filled with Hex Numbers and Printing It the Easy Way Is Pretty Pointless Because There Are Many Unprintable Elements. What I Need Is the...
I have a byte array filled with hex numbers and printing it the easy way is pretty pointless because there are many unprintable elements. What I need is the exact hexcode in the form of: 3a5f771c
33 Answers
From the discussion here, and especially this answer, this is the function I currently use:
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
My own tiny benchmarks (a million bytes a thousand times, 256 bytes 10 million times) showed it to be much faster than any other alternative, about half the time on long arrays. Compared to the answer I took it from, switching to bitwise ops --- as suggested in the discussion --- cut about 20% off of the time for long arrays. (Edit: When I say it's faster than the alternatives, I mean the alternative code offered in the discussions. Performance is equivalent to Commons Codec, which uses very similar code.)
2k20 version, with respect to Java 9 compact strings:
private static final byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII);
public static String bytesToHex(byte[] bytes) {
byte[] hexChars = new byte[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars, StandardCharsets.UTF_8);
}
The Apache Commons Codec library has a Hex class for doing just this type of work.
import org.apache.commons.codec.binary.Hex;
String foo = "I am a string";
byte[] bytes = foo.getBytes();
System.out.println( Hex.encodeHexString( bytes ) );
The method javax.xml.bind.DatatypeConverter.printHexBinary(), part of the Java Architecture for XML Binding (JAXB), was a convenient way to convert a byte[] to a hex string. The DatatypeConverter class also included many other useful data-manipulation methods.
In Java 8 and earlier, JAXB was part of the Java standard library. It was deprecated with Java 9 and removed with Java 11, as part of an effort to move all Java EE packages into their own libraries. It's a long story. Now, javax.xml.bind doesn't exist, and if you want to use JAXB, which contains DatatypeConverter, you'll need to install the JAXB API and JAXB Runtime from Maven.
Example usage:
byte bytes[] = {(byte)0, (byte)0, (byte)134, (byte)0, (byte)61};
String hex = javax.xml.bind.DatatypeConverter.printHexBinary(bytes);
Will result in:
000086003D
This answer the same as this one.
Simplest solution, no external libs, no digits constants:
public static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder(a.length * 2);
for(byte b: a)
sb.append(String.format("%02x", b));
return sb.toString();
}
Here are some common options ordered from simple (one-liner) to complex (huge library). If you are interested in performance, see the micro benchmarks below.
Must Read
Option 1: Code snippet - Simple (only using JDK/Android)
Option 1a: BigInteger
One very simple solution is to use the BigInteger's hex representation:
new BigInteger(1, someByteArray).toString(16);
Note that since this handles numbers not arbitrary byte-strings it will omit leading zeros - this may or may not be what you want (e.g. 000AE3 vs 0AE3 for a 3 byte input). This is also very slow, about 100x slower compared to option 2.
Option 1b: String.format()
Using the %X placeholder, String.format() is able to encode most primitive types (short, int, long) to hex:
String.format("%X", ByteBuffer.wrap(eightByteArray).getLong());
Option 1c: Integer/Long (only 4/8 Byte Arrays)
If you exclusively have 4 bytes arrays you can use the toHexString method of the Integer class:
Integer.toHexString(ByteBuffer.wrap(fourByteArray).getInt());
The same works with 8 byte arrays and Long
Long.toHexString(ByteBuffer.wrap(eightByteArray).getLong());