1

I have written following function to compute Md5 checksum in Java.

class Utils {
 public static String md5Hash(String input) {
        String result = "";
        try {
            System.out.println("Input=" + input);
            final MessageDigest md = MessageDigest.getInstance("MD5");
            md.reset();
            md.update(input.getBytes());
            result = md.digest().toString();
        } catch (Exception ee) {
            System.err.println("Error computing MD5 Hash");
        }
        return result;
    }
};

Calling Utils.md5Hash("abcde") multiple times gives different results. My understanding says md5 returns a deterministic and unique checksum for a string. Is that wrong? Else please let me know the bug in my implementation. Thanks

workwise
  • 1,003
  • 16
  • 33
  • Duplicate http://stackoverflow.com/questions/415953/generate-md5-hash-in-java – Endy Sep 17 '12 at 10:27
  • Not really a duplicate. I implemented this function, and wanted help with an error. That one asked for an implementation from scratch. – workwise Sep 17 '12 at 10:36
  • @workwise so you not need implementation 'from scratch'? In that case, why you not use apache library common-digest? Class `org.apache.commons.codec.digest.DigestUtils` has good implementation of varios range md5* function. – user1516873 Sep 17 '12 at 12:11

3 Answers3

7

The toString() method of a byte array doesn't return a meaningful string. It returns the type of the array object, followed by the hashCode of the array.

Transform the byte array to a String using Hex or Base64 encoding if you want it printed. Apache commons-codec has methods to do that.

Also, make sure to specify en encoding which supports any kind of character to transform your string to a byte array. The method you're using uses the platform default encoding, which could fail if, for example, it's latin-1 and you're transforming non-latin-1 characters. UTF-8 is a good choice.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
1

I have done using the following way :

 public static String encryptedLoginPassword( String password ) 
    {
        String encryptedData="";
    try{
        MessageDigest algorithm = MessageDigest.getInstance("MD5");
        byte[] defaultBytes = password.getBytes();
        algorithm.reset();
        algorithm.update(defaultBytes);
        byte messageDigest[] = algorithm.digest();

        StringBuffer hexString = new StringBuffer();
        for (int i=0;i<messageDigest.length;i++) {
            hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
        }
        encryptedData=hexString.toString();
    }catch(NoSuchAlgorithmException nsae){

    }
    return encryptedData;
    }
Dinup Kandel
  • 2,457
  • 4
  • 21
  • 38
0

int the code given by Dinup Kandel, I had to change this:

for (int i=0;i<messageDigest.length;i++) {
   hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
}

in to

 if ((0xff & messageDigest[i]) < 0x10) {
     hexString.append("0"
     + Integer.toHexString((0xFF & messageDigest[i])));
 } else {
     hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
 }

to get my unit tests working.

note: i used this to verify the correct answer:

echo -n MyTestString | md5sum
michel.iamit
  • 5,788
  • 9
  • 55
  • 74