2010-11-29 119 views
6

我不知道如何从PHP实现的这几行到Java ..MD5哈希值是不同的

$varInHex = "\x22\x33\xAd\xB5\x2b\xE6\x22\x33\x12\x36\x22\x31\xCA\x22\x11\x41\x62\x21\x22\x01\x55\x22\x71\x42\x10\x36";<br/><br/> 
$result = md5($varInHex); 
echo $result; 

嗯,我试图将它转换,但我得到不同的结果!

byte[] seq20 = new byte[]{(byte)0x22,(byte)...etc...}; 
String str = seq20.toString(); 
String result = md5(str); 
System.out.println(result); 

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]; 
     String hex = Integer.toHexString((int) 0x00FF & b); 
     if (hex.length() == 1) { 
      sb.append("0"); 
     } 
     sb.append(hex); 
    } 
    return sb.toString(); 
} 

结果在java中是导致PHP不同..

你可以帮我吗? 谢谢提前:)

回答

5

你不能直接使用seq20无需转换就那么字符串? 我会做这种方式:

md.update(seq20); 
byte[] md5sum = md.digest(); 
BigInteger bigInt = new BigInteger(1, md5sum); 
output = bigInt.toString(16); 
while (output.length() < 32) { 
    output = "0"+output; 
} 
+0

非常感谢你的伴侣!!!!!这是答案!问候! – fran 2010-11-29 14:27:59

+2

查看@adves的回答。这是一个很好的教训:如果你能提供帮助,不要将自己的解决方案推广到常见问题上,因为你不可避免地会出错。 – amalloy 2011-05-15 08:37:34

0

我的猜测是PHP评估上述作为一个字符串,而不是十六进制。 Java正在按照您的预期进行操作。

3

接受的解决方案:

md.update(seq20); 
byte[] md5sum = md.digest(); 
BigInteger bigInt = new BigInteger(1, md5sum); 
output = bigInt.toString(16); 
if (output.length() == 31) { 
    output = "0"+output; 
} 

包含系统的实现,这将失败1/256时间,因为的md5sum的输出可以有不止一个前导零。引发此错误的示例md5输入是:“15446:68106”(不含引号)。

如果您需要一个与php实现相匹配的md5,我推荐使用apache commons DigestUtils.md5Hex

5

无论其他两个答案都是肯定不对,但是从一个优雅的角度来看,考虑以下

String MD5(String... strings) { 
    MessageDigest md = null; 
    try { 
     md = MessageDigest.getInstance("MD5"); 
     for(final String s : strings) { 
      md.update(s.getBytes()); 
     } 
    } catch (NoSuchAlgorithmException ex) { 
     throw new RuntimeException("MD5 Cryptography Not Supported"); 
    } 
    final BigInteger bigInt = new BigInteger(1, md.digest()); 
    return String.format("%032x", bigInt); 
} 

编辑:采用String...可变参数是完全可选的,但它使一个小功能更容易,因为它避免了调用函数中字符串串联的开销。