Introduction
When working with byte arrays in Java, especially those containing binary data, it often becomes necessary to represent them as human-readable hexadecimal strings. This is particularly useful for debugging or when you need to display the raw bytes of a file or network transmission in a readable format. In this tutorial, we will explore several methods to convert a byte[] array into a hex string representation like 3a5f771c.
Understanding Hexadecimal Representation
Hexadecimal (or hex) is a base-16 numbering system used widely in computing as a more human-friendly representation of binary-coded values. Each hex digit represents four bits, meaning two hex digits can represent one byte. For example, the byte 0xAB would be represented as AB in hexadecimal.
Method 1: Manual Conversion
One effective way to convert a byte array to a hex string is by iterating over each byte, applying bitwise operations, and mapping them to their corresponding hex characters:
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);
}
Explanation:
HEX_ARRAYis a constant array that maps numbers to their hex character equivalents.- Each byte is converted into two hexadecimal characters by:
- Using
v >>> 4to get the high nibble (four bits). - Using
v & 0x0Fto get the low nibble.
- Using
- The result is constructed as a string and returned.
Method 2: Using Apache Commons Codec
If you are open to adding external libraries, Apache Commons Codec offers a convenient method to perform this conversion:
import org.apache.commons.codec.binary.Hex;
public class HexConverter {
public static void main(String[] args) {
String foo = "I am a string";
byte[] bytes = foo.getBytes();
System.out.println(Hex.encodeHexString(bytes));
}
}
Benefits:
- Simplicity and readability.
- Efficient for production use.
Method 3: Using javax.xml.bind.DatatypeConverter (Deprecated)
For those using Java versions prior to 11, the DatatypeConverter class in JAXB provides a straightforward method:
import javax.xml.bind.DatatypeConverter;
public class HexConverter {
public static void main(String[] args) {
byte bytes[] = {(byte)0, (byte)0, (byte)134, (byte)0, (byte)61};
String hex = DatatypeConverter.printHexBinary(bytes);
System.out.println(hex); // Output: 000086003D
}
}
Note: This method is deprecated in Java 9 and removed in Java 11. It requires adding JAXB dependencies if you’re using newer versions.
Method 4: Using StringBuilder with Formatting
This approach avoids external libraries and constants, utilizing the built-in String.format method:
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();
}
Explanation:
StringBuilderis used to efficiently construct the resulting string.%02xformats each byte as a two-digit hex number, padding with zero if necessary.
Conclusion
Each method has its advantages. The manual conversion approach provides a lightweight solution without dependencies, while Apache Commons Codec simplifies the code at the cost of adding an external library. The StringBuilder method offers flexibility and readability without any additional libraries. Choose the method that best fits your project’s needs and constraints.