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_ARRAY
is a constant array that maps numbers to their hex character equivalents.- Each byte is converted into two hexadecimal characters by:
- Using
v >>> 4
to get the high nibble (four bits). - Using
v & 0x0F
to 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:
StringBuilder
is used to efficiently construct the resulting string.%02x
formats 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.