Explain Codes LogoExplain Codes Logo

Convert a string representation of a hex dump to a byte array using Java?

java
hex-conversion
byte-array
java-utility
Alex KataevbyAlex Kataev·Sep 25, 2024
TLDR

Transform a hex string to a byte array in Java swiftly with the following code:

public static byte[] hexToBytes(String hex) { byte[] bytes = new byte[hex.length() / 2]; for (int i = 0; i < bytes.length; i++) { int index = i * 2; bytes[i] = (byte) Integer.parseInt(hex.substring(index, index + 2), 16); } return bytes; }

Apply it as below:

byte[] byteArray = hexToBytes("deadbeef");

This efficient function deciphers each hexadecimal pair to a byte, populating your byte[] with correct values.

Comprehensive understanding

Although our fast answer provides a quick fix, let's delve into enhanced methods and key aspects that could diversify the solution.

Java utility: HexFormat class

Are you living in a dark mode theme? Brighten up your code with Java 17's HexFormat! 😎 Not only this class provides a quick fix but also grapples with leading zeros and pesky negative byte values.

import java.util.HexFormat; public static byte[] hexToBytesHexFormat(String hex) { HexFormat hexFormat = HexFormat.of(); return hexFormat.parseHex(hex); }

Compatibility and dependency checks

Say goodbye to "ClassNotFound" woes with these alternatives suitable for different Java versions and execution environment contexts!

  • DatatypeConverter.parseHexBinary - A friend in need for Java 8, missing in Java 9+ without the java.xml.bind module.

    import javax.xml.bind.DatatypeConverter; byte[] bytes = DatatypeConverter.parseHexBinary(hex);
  • Apache's Hex.decodeHex() - A third-wheeling friend that doesn't shy away from odd-length strings.

    import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; public static byte[] hexToBytesApache(String hex) throws DecoderException { return Hex.decodeHex(hex); // P.S. You have a DecoderException, call Sherlock! 🔍 }
  • Google's Guava BaseEncoding.base16() - Your nerdy friend who makes things look easy-peasy lemon squeezy!

    import com.google.common.io.BaseEncoding; byte[] bytes = BaseEncoding.base16().lowerCase().decode(hex.toLowerCase()); // P.S. Even hex strings can have a lower case complex! 😉

One-liner wonder: BigInteger

With BigInteger, less is definitely more! Yet, beware of the leading zeros playing hide-and-seek due to the mischievous toByteArray() method:

import java.math.BigInteger; public static byte[] hexToBytesBigInteger(String hex) { return new BigInteger("1" + hex, 16).toByteArray(); // P.S. Prepend "1" to play hide and seek with leading zeros! }

A folly of pitfalls

Here's how you can equip your code to boldly face the infamous edge cases:

  • Check for Null and empty strings - To keep NullPointerException or IndexOutOfBoundsException at bay.

    if (hex == null || hex.isEmpty()) { return new byte[0]; // P.S. I comment better with ☕️. }
  • Fire an alarm if the input hex string is anything beyond [0-9a-fA-F] or is of odd length!

    if (hex.length() % 2 != 0) { throw new IllegalArgumentException("Hex string must have an even length"); // P.S. Hex strings also pair up... Forever alone no more. }
  • Boost performance, assemble a lookup table to convert hex characters to byte values without parsing.

  • Be a memory-friendly coder, consider the cost of intermediate objects and target in-place parsing.