56

For logging purpose we are converting the logs to byte array and then to hex string. I want to get it back in a Java String, but I am not able to do so.

The hex string in log file looks something like

fd00000aa8660b5b010006acdc0100000101000100010000

How can I decode this?

0

7 Answers 7

77

Using Hex in Apache Commons:

String hexString = "fd00000aa8660b5b010006acdc0100000101000100010000";    
byte[] bytes = Hex.decodeHex(hexString.toCharArray());
System.out.println(new String(bytes, "UTF-8"));
Sign up to request clarification or add additional context in comments.

4 Comments

Hex is now part of Apache Commons Codec
Here the dependency: <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.12</version> </dependency>
It doesn’t need much to recognize, that this data is not a UTF-8 encoded string and new String(bytes, "UTF-8") will just produce garbage.
<!-- mvnrepository.com/artifact/commons-codec/commons-codec --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency>
36
byte[] bytes = javax.xml.bind.DatatypeConverter.parseHexBinary(hexString);
String result= new String(bytes, encoding);

5 Comments

Where the heck do I find DatatypeConverter?
Not public anymore in recent Java versions
javax.xml.bind.DatatypeConverter
what are the encoding values?
13

You can go from String (hex) to byte array to String as UTF-8(?). Make sure your hex string does not have leading spaces and stuff.

public static byte[] hexStringToByteArray(String hex) {
    int l = hex.length();
    byte[] data = new byte[l / 2];
    for (int i = 0; i < l; i += 2) {
        data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                + Character.digit(hex.charAt(i + 1), 16));
    }
    return data;
}

Usage:

String b = "0xfd00000aa8660b5b010006acdc0100000101000100010000";
byte[] bytes = hexStringToByteArray(b);
String st = new String(bytes, StandardCharsets.UTF_8);
System.out.println(st);

2 Comments

how to do ot for versions below kitkat?
may I ask what is the purpose of converting it to String as UTF-8?
10

First of all read in the data, then convert it to byte array:

 byte b = Byte.parseByte(str, 16); 

and then use String constructor:

new String(byte[] bytes) 

or if the charset is not system default then:

new String(byte[] bytes, String charsetName) 

7 Comments

Of course, it may or may not work depending on encoding used by "some other guys". Maybe they used Latin-9. Or UTF-8. Or EUC-JP. Or maybe it was in Big-Endian. Who knows?
That's why you should specify the encoding which was used by log strings before conversion to hex string.
use Byte.parseByte(str, 16); to parse a hexadecimal number.
The String constructor expects a byte array and not just byte, I tried and it failed.
@zundi in first line you parse only single byte. So you need to use a loop to get all the bytes and put them in array. Please look at Munene iUwej Julius answer. His method is doing just that
|
6

Try the following code:

public static byte[] decode(String hex){

        String[] list=hex.split("(?<=\\G.{2})");
        ByteBuffer buffer= ByteBuffer.allocate(list.length);
        System.out.println(list.length);
        for(String str: list)
            buffer.put(Byte.parseByte(str,16));

        return buffer.array();

}

To convert to String just create a new String with the byte[] returned by the decode method.

3 Comments

I changed Byte.parseByte to (byte)Integer.parseInteger to allow for numbers > 128 to be parsed.
@domenukk it's Integer.parseInt(..) not Integer.parseInteger(..) . Byte.parseByte implemented as follow { return (byte) Integer.parseInt(Str, base);}
@Munene thanx 4 regex
6

Just another way to convert hex string to java string:

public static String unHex(String arg) {        

    String str = "";
    for(int i=0;i<arg.length();i+=2)
    {
        String s = arg.substring(i, (i + 2));
        int decimal = Integer.parseInt(s, 16);
        str = str + (char) decimal;
    }       
    return str;
}

2 Comments

Lots of substrings being created. Not ideal.
replace "String str" with a StringBuffer(), and use sb.append(char) if performance is an issue.
6

There is yet another way to do this if using JDK17 or above, see the new HexFormat class which has useful methods for converting byte[] <=> hexadecimal String :

String hexStr ="5468697320697320616e206578616d706c6520737472696e67";
byte[] bytes = HexFormat.of().parseHex(hexStr);
String str = new String(bytes, StandardCharsets.UTF_8 /* or Charset.forName("whateverencoding")*/);

You of course need to know the exact character encoding of the hexadecimal representation in order to generate the correct String value.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.