2009-06-23 140 views
9

下一個函數在MySQLMySQL的MD5和Java MD5不等於

MD5( 'secret')產生5ebe2294ecd0e0f08eab7690d2a6ee69

我想有一個Java函數生成相同的輸出。但

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

生成基地16

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

回答

24

嘗試編碼只是爲了讓你開始... 94基地16 5E。

**編輯:**試着改變你的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:若B <0x10的,則需要墊0 – laalto 2009-06-23 17:33:21

+0

優秀點;編輯爲包含@ mihi的檢查(這比IMO字節值檢查更好)。 – Randolpho 2009-06-23 17:37:08

+0

你忘了()在hex.length() – 2009-06-23 17:45:03

2

考慮轉換你的十進制字節爲十六進制。例如94個鹼基10是5e鹼基16.

3

這兩個是相等的。 Java似乎是十進制的。將其轉換爲十六進制。

2

這是因爲基地不同。 MySQL MD5結果基於16,而Java MD5基於10。

我希望我可以幫助你,但我的數學很臭。我的一位朋友幫助我用PHP中的16進制校驗和生成了一個10進制的校驗和,但是我失去了腳本。希望你能基於此找到你的答案。

6

取代

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

通過

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

如果可以的話,我會給你超過+1的。 :) – Randolpho 2009-06-23 18:22:23

0

而不是重新發明輪子,嘗試阿帕奇公地編解碼器(http://commons.apache.org/codec/),其將處理的十六進制編碼您Hex.encodeHex(字節[])

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

這可以通過使用實用程序類縮短爲單線程從Apache共享編解碼器庫S(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

看看我是怎麼做的,代碼是自解釋的!

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

輸出:

MD5:明文:5ab677ec767735cebd67407005786016

MySQL查詢產生相同散列:

SELECT md5('cleartext'); 

輸出:

MD5( '明文')
5ab677ec767735cebd67407005786016