Question

The next function in MySQL

MD5( 'secret' ) generates 5ebe2294ecd0e0f08eab7690d2a6ee69

I would like to have a Java function to generate the same output. But

public static String md5( String source ) {
    try {
        MessageDigest md = MessageDigest.getInstance( "MD5" );
        byte[] bytes = md.digest( source.getBytes("UTF-8") );
        return getString( bytes );
    } catch( Exception e )  {
        e.printStackTrace();
        return null;
    }
}

private static String getString( byte[] bytes ) {
    StringBuffer sb = new StringBuffer();
    for( int i=0; i<bytes.length; i++ ) {
        byte b = bytes[ i ];
        sb.append( ( int )( 0x00FF & b ) );
        if( i+1 <bytes.length ) {
            sb.append( "-" );
        }
    }
    return sb.toString();
}

generates

94-190-34-148-236-208-224-240-142-171-118-144-210-166-238-105
Was it helpful?

Solution

Try encoding in base 16. Just to get you started... 94 in base 16 is 5E.

**Edit:**Try changing your getString method:

private static String getString( byte[] bytes ) 
{
  StringBuffer sb = new StringBuffer();
  for( int i=0; i<bytes.length; i++ )     
  {
     byte b = bytes[ i ];
     String hex = Integer.toHexString((int) 0x00FF & b);
     if (hex.length() == 1) 
     {
        sb.append("0");
     }
     sb.append( hex );
  }
  return sb.toString();
}

OTHER TIPS

replace

sb.append( ( int )( 0x00FF & b ) );
if( i+1 <bytes.length ) {
    sb.append( "-" );
}

by

String hex = Integer.toHexString((int) 0x00FF & b);
if (hex.length == 1) sb.append("0");
sb.append( hex );

This can be shortened to a one-liner by using the utility classes from the Apache Commons Codec library (http://commons.apache.org/codec)

String md = org.apache.commons.codec.digest.DigestUtils.md5hex("whatever");

Those two are equal. The Java one appears to be in decimal. Convert it to hexadecimal.

Consider converting your decimal bytes to hexadecimal. For example 94 base 10 is 5e base 16.

That's because the base is different. The MySQL MD5 result is in base-16, while the Java MD5 is in base-10.

I wish I could help you further, but my math stinks. A friend of mine helped me generate a base-10 checksum from a base-16 checksum in PHP, but I've lost the script. Hope you can find your answer based on this.

String password = org.springframework.util.DigestUtils.md5DigestAsHex("password".getBytes())
System.out.println(password)

Look how I do it, the code is self explainable!

Java code:

public static void main(String a[]) throws NoSuchAlgorithmException {
    String passClear = "cleartext";
    MessageDigest md5 = MessageDigest.getInstance("MD5"); // you can change it to SHA1 if needed!
    md5.update(passClear.getBytes(), 0, passClear.length());
    System.out.printf("MD5: %s: %s ", passClear, new BigInteger(1, md5.digest()).toString(16));
}

Output:

MD5: cleartext: 5ab677ec767735cebd67407005786016

Mysql query that produces the same hash:

SELECT md5( 'cleartext' ); 

Output:

md5('cleartext')
5ab677ec767735cebd67407005786016

Rather than reinventing the wheel, try Apache commons codec (http://commons.apache.org/codec/) which will handle the hex encoding for you with Hex.encodeHex(byte[])

private String encodeAsMD5(String password) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] bytes = md.digest(password.getBytes());
        return new String(Hex.encodeHex(bytes));
    } 
    catch(Exception e) {
        e.printStackTrace();
        return null;
    }
}

Use the utility classes from the Apache Commons Codec library: http://commons.apache.org/codec/

String password = org.apache.commons.codec.digest.DigestUtils.md5Hex("password");
System.out.println(password);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top