How to Convert a Byte Array to a Hex String in Java

How to convert a byte array to a hex string in Java?

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);
}

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

Update (2021) - Java 17 now includes java.util.HexFormat (only took 25 years):

HexFormat.of().parseHex(s)


For older versions of Java:

Here's a solution that I think is better than any posted so far:

/* s must be an even-length string. */
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}

Reasons why it is an improvement:

  • Safe with leading zeros (unlike BigInteger) and with negative byte values (unlike Byte.parseByte)

  • Doesn't convert the String into a char[], or create StringBuilder and String objects for every single byte.

  • No library dependencies that may not be available

Feel free to add argument checking via assert or exceptions if the argument is not known to be safe.

How to Convert byte array to hexString in java?

You need to look at String.format() and the Formatter specifications.

e.g.

String.format("%02x", byteValue);

Iterate through the array and append each String.format() result to a StringBuilder

Converting a byte array into a hex string

As I am on Kotlin 1.3 you may also be interested in the UByte soon (note that it's an experimental feature. See also Kotlin 1.3M1 and 1.3M2 announcement)

E.g.:

@ExperimentalUnsignedTypes // just to make it clear that the experimental unsigned types are used
fun ByteArray.toHexString() = asUByteArray().joinToString("") { it.toString(16).padStart(2, '0') }

The formatting option is probably the nicest other variant (but maybe not that easily readable... and I always forget how it works, so it is definitely not so easy to remember (for me :-)):

fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) }

How to convert a byte array to hex string?

An easy way to convert byte[] to String is using BigInteger:

String s = new BigInteger(1, data).toString(16);

In smali you need two additional registers (or two registers that can be overwritten). In the following code v1 and v2 is used. The byte array has to be present in v4:

new-instance v1, Ljava/math/BigInteger;

const/4 v2, 0x1 # interpret the byte array as positive number

invoke-direct {v1, v2, v4}, Ljava/math/BigInteger;-><init>(I[B)V

const/16 v2, 0x10 # Output base 16 = hexadeximal

invoke-virtual {v1, v2}, Ljava/math/BigInteger;->toString(I)Ljava/lang/String;

move-result-object v1

# The hex-string is now in v1

# Let's log the value
const-string v2, "TAG"

invoke-static {v2, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

There is a very simple way to generate such smali code yourself:

Take an any app you have the Android Studio source code of or create a new Android project using Android Studio. Add a method in the main activity and paste the java code you want the smali code of. Now compile the app to an APK and open it in Jadx. Seelct the activity class you have added the method to switch to the Smali view. Now you can simply copy the samli code, just some registers may have to be adapted (e.g. inthis case the v4 registers which has the byte[] input.

In Java, how do I convert a byte array to a string of hex digits while keeping leading zeros?

A simple approach would be to check how many digits are output by Integer.toHexString() and add a leading zero to each byte if needed. Something like this:

public static String toHexString(byte[] bytes) {
StringBuilder hexString = new StringBuilder();

for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(0xFF & bytes[i]);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}

return hexString.toString();
}

Convert byte array represented as hexadecimal string to correct int

Byte array contains the byte representation of a string.

In ASCII:

  • 102 == 'f'
  • 100 == 'd'
  • 51 == '3'
  • 52 == '4'
  • 48 == '0'

You should convert from byte array to string and then parse that string using base 16 (hexadecimal).

String hex = new String(arr, "ASCII"); //fd3400
int number = Integer.valueOf(hex, 16).intValue(); //16593920

Why to convert byte array to hex string?

For example:

  • To store in a file with a format that doesn't support binary, e.g. CSV.
  • To store in a database field that doesn't support binary.
  • To send in a protocol that doesn't support binary.
  • To embed in other content that doesn't support binary, e.g. XML and JSON.
  • To display to a user.
  • Many other reasons...


Related Topics



Leave a reply



Submit