views:

1406

answers:

6

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
+18  A: 

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();
}
Randolpho
@Randolpho: if b < 0x10, you need to pad with 0
laalto
Excellent point; edited to include @mihi's check (which is better IMO than a byte value check).
Randolpho
you forgot the () in hex.length()
Sergio del Amo
Ahh, the perils of copy/paste. :) Fixed.
Randolpho
+2  A: 

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

laalto
+2  A: 

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

Thanatos
+2  A: 

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.

nikc
+5  A: 

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 );
mihi
I'd give you more than +1 if I could. :)
Randolpho
A: 

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;
    }
}
James Frost