2009-06-23 14 views
9

Kolejna funkcja MySQLMySQL MD5 i MD5 Java nie równa

MD5( 'secret') generuje 5ebe2294ecd0e0f08eab7690d2a6ee69

chciałbym mieć funkcję Java, aby wygenerować taką samą moc. Ale

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

generuje kodowanie

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

Odpowiedz

24

Spróbuj w bazie 16. Wystarczy, aby dostać się zaczęło ... 94 w bazie 16 jest 5E.

** Edit: ** Spróbuj zmienić metodę 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(); 
} 
+0

@Randolpho: jeśli b <0x10, musisz pad z 0 – laalto

+0

doskonały punkt; edytowane w celu uwzględnienia czeku @ mihi (co jest lepszym IMO niż sprawdzanie wartości bajtów). – Randolpho

+0

zapomniałeś() w hex.length() –

2

Rozważmy konwersja bajtów dziesiętne na szesnastkowe. Na przykład 94 baza 10 to 5e podstawa 16.

3

Te dwie są równe. Java wydaje się być dziesiętna. Konwertuj na szesnastkowy.

2

To dlatego, że podstawa jest inna. Wynik MySQL MD5 znajduje się w base-16, a Java MD5 w base-10.

Chciałbym móc ci jeszcze pomóc, ale moja matematyka śmierdzi. Mój znajomy pomógł mi wygenerować sumę kontrolną base-10 z sumy kontrolnej base-16 w PHP, ale straciłem skrypt. Mam nadzieję, że na tej podstawie znajdziesz swoją odpowiedź.

6

zastąpić

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

przez

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

Dałbym ci więcej niż +1, gdybym mógł. :) – Randolpho

0

Zamiast wymyślania koła, spróbuj Apache Commons kodek (http://commons.apache.org/codec/), która będzie obsługiwać kodowanie hex dla Ciebie z 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; 
    } 
} 
4

Można to skrócić do jednego liniowca za pomocą narzędzia classe s z biblioteki Apache Commons Codec (http://commons.apache.org/codec)

String md = org.apache.commons.codec.digest.DigestUtils.md5hex("whatever"); 
1
String password = org.springframework.util.DigestUtils.md5DigestAsHex("password".getBytes()) 
System.out.println(password) 
0

Spójrz, jak to zrobić, kod jest samo wytłumaczalne !Kod

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

wyjściowa:

MD5: zwykłego tekstu: 5ab677ec767735cebd67407005786016

Mysql zapytanie, które daje ten sam hash:

SELECT md5('cleartext'); 

wyjściowy:

md5 ('zwykłego tekstu')
5ab677ec767735cebd67407005786016