NoNaMe
NoNaMe

Reputation: 6242

Issue with MD5 hash generation

I am using following code to generate MD5 Hash for my application it encodes some string value and then I send this generated hash through my web service to some .Net code, that code read my MD5 hash and generate MD5 of the string the strings he is getting from DB and then compare them

public static String getMD5Hash(String val) throws Exception {
        byte[] bytes = val.getBytes();

        MessageDigest m = MessageDigest.getInstance("MD5");
        byte[] digest = m.digest(bytes);
        String hash = new BigInteger(1, digest).toString(16);
        System.out.println(hash.length());
        return hash;
    }

    public static void main(String[] asd) throws Exception{
        for(int i=0;i<10;i++){
            System.out.println(getMD5Hash(i+Math.pow(10, i)+""));//for testing
            System.out.println(getMD5Hash(i+""));//for testing
        }
    }

The issue is as i am getting converted hash from BigInteger and some times generated hash starts with a 0 in that case Biginteger does not consider that 0 and on the other side when .Net generates that hash of the same string it generate it with 0 and in this way string comparison return false, e-g hash code i generate and send "102678D1922799CF9122B3F103975F1" where in .Net hash is "0102678D1922799CF9122B3F103975F1"

also some times it generate code like

.Net generates  0012678D1922799CF9122B3F103975F1 and java 12678D1922799CF9122B3F103975F1 

OR

0002678D1922799CF9122B3F103975F1 and 2678D1922799CF9122B3F103975F1

How can i get this code with all 0s that are in start. Thanks in advance.

Upvotes: 0

Views: 1887

Answers (2)

Jeff Bowman
Jeff Bowman

Reputation: 95724

I don't think there's a better way using MessageDigest than just padding the String:

// ...
StringBuilder builder = new StringBuilder();
for (int i = hash.length(); i < 64; i++) {
  builder.append('0');
}
builder.append(hash);
return builder.toString();

...but you can use Guava's Strings.padStart():

// ...
return Strings.padStart(hash, 64, '0');

...or even use Guava's hashing library, which returns the exact same strings as your function (I just checked):

public static String getMD5Hash(String val) throws Exception {
  return Hashing.md5().hashBytes(val.getBytes()).toString();
}

Upvotes: 4

kichik
kichik

Reputation: 34744

This question has some better methods of generating the hex string:

In Java, how do I convert a byte array to a string of hex digits while keeping leading zeros?

Since you're already using BigInteger, this seems like the best solution:

BigInteger bi = new BigInteger(1, digest);
String hash = String.format("%0" + (digest.length << 1) + "X", bi);

Upvotes: 3

Related Questions