Hex-string representation of a byte array I have a legacy method toHex(byte[]) used in my application since the beginning of time to store a hexadecimal representation of a byte[] into the database. The byte[] buffer is a SHA256 checksum of a file, which is computed consistently.

Since this method is embodied as private method in a class, in order to compare the SHA256 of two files I could either copy the implementation to my other class or use a library-provided implementation. In fact I found org.apache.cxf.common.util.StringUtils.toHexString

This is CXF code:


/*     */   public static String toHexString(byte[] bytes) {
/* 215 */     StringBuilder hexString = new StringBuilder();
/* 216 */     for (int i = 0; i &lt; bytes.length; ++i) {
/* 217 */       hexString.append(Integer.toHexString(0xFF &amp; bytes[i]));
/*     */     }
/* 219 */     return hexString.toString();
/*     */   }



This is my code:

private static String toHex(byte[] checksumArray)
{
    StringBuilder result = new StringBuilder();
    for (byte checksumByte : checksumArray)
    {
        String hex = Integer.toString((checksumByte &amp; 0xff) + 0x100, 16).substring(1);
        result.append(hex);
    }
    return result.toString();
}


I can see the two implementations are different, but I am not understanding in what they differ.

This is example data returned by the two implementations:

CXF : 99dd29352b873ccb7f17e43984c0c984288a397a308cd63b47537968eee991
Me  : 99dd29352b873ccb7f17e43984c00c9804288a397a308cd63b47537968eee991
Diff: 99dd29352b873ccb7f17e43984c0^c98^4288a397a308cd63b47537968eee991


As you can see "my" hex string is longer because of a couple of zeroes.
If I use the same implementation of toHexString to compare the SHA256 stored in database with the actual SHA256 of a file, I get consistent result. But if I try to use an authoritative implementation (assuming people at Apache Foundation write good code) I get a different result.

Is it a bug in my code? Unfortunately I don't know anything about that implementation, I just inherited the code.
Can someone explain me the algorithm behind my implementation compared with CXF's implementation?

In the meantime, can somebody recommend an "official" reference implementation of the conversion from byte[] to hex string?
Your code is good. The CXF code has a bug, and is missing leading-zero values when the byte value is less than 16.

Your code can be improved, though. It's doing a lot more work than it needs to do get the characters right.

Converting the value to a "longer" string and then taking the substring is a long-winded way of getting the padding right.

Consider a lookup-table for the task, and then use that as a mechanism for fast string building using a char array.

I have had a lot of success with this method:

private static final char[] hexchars = "0123456789abcdef".toCharArray();

private static String toHexRL(byte[] checksumArray) {
    int len = checksumArray.length * 2;
    char[] hchars = new char[len];
    int pos = 0;
    for (byte b : checksumArray) {
        hchars[pos++] = hexchars[(b&gt;&gt;4) &amp; 0xf];
        hchars[pos++] = hexchars[b &amp; 0xf];
    }
    return new String(hchars);
}


Note, I have put your method, my method, and the CXF method in to a test case here on Ideone: https://ideone.com/o66K1P

Note: To my knowledge, there's no authoritative (Java core library) for converting an array of byte to a hex string.