13

I know that you can use printf and also use StringBuilder.append(String.format("%x", byte)) to convert values to HEX values and display them on the console. But I want to be able to actually format the byte array so that each byte is displayed as HEX instead of decimal.

Here is a section of my code that I have already that does the first two ways that I stated:

if(bytes > 0)
    {
        byteArray = new byte[bytes]; // Set up array to receive these values.

        for(int i=0; i<bytes; i++)
        {
            byteString = hexSubString(hexString, offSet, CHARSPERBYTE, false); // Isolate digits for a single byte.
            Log.d("HEXSTRING", byteString);

            if(byteString.length() > 0)
            {
                byteArray[i] = (byte)Integer.parseInt(byteString, 16); // Parse value into binary data array.
            }
            else
            {
                System.out.println("String is empty!");
            }

            offSet += CHARSPERBYTE; // Set up for next word hex.    
        }

        StringBuilder sb = new StringBuilder();
        for(byte b : byteArray)
        {
            sb.append(String.format("%x", b));
        }

        byte subSystem = byteArray[0];
        byte highLevel = byteArray[1];
        byte lowLevel = byteArray[2];

        System.out.println("Byte array size: " + byteArray.length);
        System.out.printf("Byte 1: " + "%x", subSystem);
        System.out.printf("Byte 2: " + "%x", highLevel);
        System.out.println("Byte 3: " + lowLevel);
        System.out.println("Byte array value: " + Arrays.toString(byteArray));
        System.out.println("Byte array values as HEX: " + sb.toString());
    }
    else
    {
        byteArray = new byte[0]; // No hex data.

        //throw new HexException();
    }

    return byteArray;

The string that was split up into the byte array was:

"1E2021345A2B"

But displays it as decimal on the console as:

"303233529043"

Could anyone please help me on how to get the actual values to be in hex and be displayed in that way naturally. Thank you in advance.

1
  • Why don't you just call Integer.parseInt(sb.toString(), 16) ? Commented Oct 18, 2013 at 13:19

4 Answers 4

31

You can use the String javax.xml.bind.DatatypeConverter.printHexBinary(byte[]). e.g.:

public static void main(String[] args) {
    byte[] array = new byte[] { 127, 15, 0 };
    String hex = DatatypeConverter.printHexBinary(array);
    System.out.println(hex); // prints "7F0F00"
}
Sign up to request clarification or add additional context in comments.

5 Comments

I am using Android Java and Android doesn't support this. Is there another way around this?
The shortest way of any other ways I found.
VGR's answer also works on Android and it's much simpler.
@JamesMeade For Android, see the VGR's solution.
Top answer for business applications, where javax.xml.bind.DatatypeConverter usually is available
28

String.format actually makes use of the java.util.Formatter class. Instead of using the String.format convenience method, use a Formatter directly:

Formatter formatter = new Formatter();
for (byte b : bytes) {
    formatter.format("%02x", b);
}
String hex = formatter.toString();

As of Java 17, HexFormat can do this in one line:

String hex = HexFormat.of().formatHex(bytes);

4 Comments

This is the shortest, simplest answer to this question I've been able to find which does not rely on non-standard libraries. Very excellent!!!
Cleanest solution by far. Thank you! Worth mentioning that you can put x in uppercase and add a white space after it in the upper case to make it look more readable
Does this pad a zero if the last byte is less than 16?
@ConstanceEustace The 0 in %02x means ‘pad with zero if necessary to guarantee there are two digits.’ From the documentation: “If the '0' flag is given then the output will be padded to the field width with leading zeros after the radix indicator or sign (if present).”
6

The way I do it:

  private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
      'B', 'C', 'D', 'E', 'F' };

  public static String toHexString(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    int v;
    for (int j = 0; j < bytes.length; j++) {
      v = bytes[j] & 0xFF;
      hexChars[j * 2] = HEX_CHARS[v >>> 4];
      hexChars[j * 2 + 1] = HEX_CHARS[v & 0x0F];
    }
    return new String(hexChars);
  }

10 Comments

I still want to return a byte array though where each byte has been formatted to hex. e.g. the string was 1E and the byte is now 30 in decimal and I want the byte to be formatted back to 1E. Is there a way of doing this?
It requires two HEX characters to 'describe' 1 byte. You can represent 1 hex characters using 1 byte, if you encode the hex char using the hex chrar's ASCII code. Hence, you need two bytes to describe one byte in hex, in ASCII. I'm not sure what you really want.
I want to have two characters occupying 1 single byte. So for my example, I have a byte array of 6.
You should learn about bytes, numeral systems, characters and their encoding in bits, called 'character encoding'. By default, an ascii character is encoded using 1 byte (8 bits). Hexadecimal is a numeral system where each number can span from 0-F. This number can be represented by an ascii character. You need two hex numbers to describe a byte (8 bits). If you want to display these two numbers using ascii characters, then you need two characters and thus two bytes.
And this that is exactly about conversion between numeral systems: youtube.com/watch?v=Fpm-E5v6ddc
|
2

Try this

byte[] raw = some_bytes;
javax.xml.bind.DatatypeConverter.printHexBinary(raw)

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.