Posts Tagged 32 bytes

MD5 generates 31 bytes instead of 32

I wrote the following method to generate MD5 hashes:

private static String md5(String input) throws NoSuchAlgorithmException {
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] messageDigest = md.digest(input.getBytes());
    BigInteger number = new BigInteger(1, messageDigest);
    return number.toString(16);
}

This method takes a String and outputs a 32 character hash.

However, depending on the value of the parameter, this method outputs a 31 character hash instead of 32.
Why is that?

It appears that it is because the leading zero is missing. But the question remains! Why?
This is simply because the toString method doesn’t know that we are expecting a leading zero. BigInteger stores just a number; it doesn’t know how many leading zeroes we need.

For example, how many leading zero would you expect with the following code?

new BigInteger("33").toString()

In order to be sure MD5 generates 32 bytes, we could replace the number.toString(16) by:

String.format("%032x", number)

So, the method will look like the following:

private static String md5(String input) throws NoSuchAlgorithmException {
    MessageDigest md = MessageDigest.getInstance("MD5");
    byte[] messageDigest = md.digest(input.getBytes());
    BigInteger number = new BigInteger(1, messageDigest);
    return String.format("%032x", number);
}

, , , ,

No Comments