Pregunta

La próxima función en MySQL

MD5 ('secreto') genera 5ebe2294ecd0e0f08eab7690d2a6ee69

Me gustaría tener una función Java para generar la misma salida. Pero

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();
}

genera

94-190-34-148-236-208-224-240-142-171-118-144-210-166-238-105
¿Fue útil?

Solución

Intente codificar en la base 16. Solo para comenzar ... 94 en la base 16 es 5E.

** Editar: ** Intente cambiar su método getString:

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();
}

Otros consejos

reemplazar

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

por

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

Esto se puede acortar a una línea usando las clases de utilidad de la biblioteca de códecs de Apache Commons ( http: / /commons.apache.org/codec )

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

Esos dos son iguales. El de Java parece estar en decimal. Conviértalo a hexadecimal.

Considere convertir sus bytes decimales a hexadecimales. Por ejemplo, 94 base 10 es 5e base 16.

Eso es porque la base es diferente. El resultado de MySQL MD5 está en base-16, mientras que el Java MD5 está en base-10.

Desearía poder ayudarte más, pero mi matemática apesta. Un amigo mío me ayudó a generar una suma de comprobación de base 10 a partir de una suma de comprobación de base 16 en PHP, pero he perdido el script. Espero que puedas encontrar tu respuesta en base a esto.

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

¡Mira cómo lo hago, el código se explica por sí mismo!

Código Java:

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));
}

Salida:

MD5: texto en claro: 5ab677ec767735cebd67407005786016

Consulta Mysql que produce el mismo hash:

SELECT md5( 'cleartext' ); 

Salida:

md5 ('texto claro')
5ab677ec767735cebd67407005786016

En lugar de reinventar la rueda, intente el códec de Apache commons ( http://commons.apache.org/codec / ) que manejará la codificación hexadecimal para usted con 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;
    }
}

Utilice las clases de utilidad de la biblioteca de códecs de Apache Commons: http://commons.apache.org/codec/

String password = org.apache.commons.codec.digest.DigestUtils.md5Hex("password");
System.out.println(password);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top