IMHO all the solutions above that provide snippets to remove the leading zeroes are wrong.
byte messageDigest[] = algorithm.digest();
for (int i = 0; i < messageDigest.length; i++) {
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
}
According to this snippet, 8 bits are taken from the byte array in an
iteration, converted into an integer (since Integer.toHexString function takes
int as argument) and then that integer is converted to the corresponding hash
value. So, for example if you have 00000001 00000001 in binary, according to
the code, the hexString variable would have 0x11 as the hex value whereas
correct value should be 0x0101. Thus, while calculating MD5 we may get hashes
of length <32 bytes(because of missing zeroes) which may not satisfy the
cryptographically unique properties that MD5 hash does.
The solution to the problem is replacing the above code snippet by the
following snippet:
byte messageDigest[] = algorithm.digest();
for (int i = 0; i < messageDigest.length; i++) {
int temp=0xFF & messageDigest[i];
String s=Integer.toHexString(temp);
if(temp<=0x0F){
s="0"+s;
}
hexString.append(s);
}