Java 计算 MD5 哈希值

15
http://www.anyexample.com/programming/java/java_simple_class_to_compute_md5_hash.xml中提供了一个示例,说明如何计算字符串的MD5哈希值。这将导致一个20位十六进制字符串。根据http://en.wikipedia.org/wiki/MD5,我期望看到一个32位的十六进制字符串。例如在How can I generate an MD5 hash?中,使用dac2009的响应也得到了相同的结果。
为什么我得到的东西看起来像是MD5哈希,但实际上并不是?我无法想象得到的所有字符串都必须用12个前导零来填充。
编辑:一个代码示例
public static String MungPass(String pass) throws NoSuchAlgorithmException {
    MessageDigest m = MessageDigest.getInstance("MD5");
    byte[] data = pass.getBytes(); 
    m.update(data,0,data.length);
    BigInteger i = new BigInteger(1,m.digest());
    return String.format("%1$032X", i);
}

源自http://snippets.dzone.com/posts/show/3686


你的第一个链接是404。 - Paul
2
请发布一个简短的示例代码,以演示您遇到的问题。如果没有这个,我们无法告诉您您做错了什么 :) 您链接到的StackOverflow问题中描述的方法是生成MD5哈希的方法,确实是32个十六进制字符。 - Brian Roach
代码示例已添加,但给定链接中提供的任何代码仅显示20个数字。我粘贴的代码为输入“java”生成MD5“93F725A07423FE1C889F”,这是20位十六进制数。 - AndyAndroid
4个回答

47

使用 org.apache.commons.codec.digest.DigestUtils 代替:

DigestUtils.md5Hex(str);

这将会给你一个32个字符的字符串作为结果。


2
由于这是一个移动应用程序,我不想使用任何额外的软件包,而是希望使用“纯Java”。 - AndyAndroid
5
这个话题的标题是误导性的,因为没有提到移动设备。例如,对我来说,这个答案非常有用且简单,因为我在寻找一个简单的Java示例。这个答案对我来说非常完美 :) - sarkiroka
1
@sarkiroka 如果标题/标签中提到了“移动”,您可能也不会尝试打开此页面。如果 OP 不喜欢特定的答案,他有权这样做。没有必要把它当作冒犯。 :) - Sufian

4

你可能遗漏了什么。链接的代码完全正常。请确保问题与显示结果无关。有可能的原因:

  • 在 GUI 中窗口太小
  • 在控制台存在多线程问题
  • 在网络包被过早截断的情况下超长
  • 你将长度裁剪为 20,而不是 0x20,后者是 32

我按照第一个链接中给出的做了 --> 20个字符,我看了第二个链接 --> 对那篇文章进行评论:它忽略尾随空格。因此,似乎两种方法都不能很好地工作。你成功运行了吗? - AndyAndroid
好的,我把我的返回语句改成了 "return i.toString(16);"。但是我仍然得到了相同的结果。20位数字。你运行代码并得到32位数字了吗? - AndyAndroid
重新安装不可能,它运行在一个Android手机上,但你是对的,我尝试在一个普通的桌面Java安装中,那里是32位数字。也许是Android中的一个错误。感谢您的所有帮助。 - AndyAndroid
“在我看来,这是糟糕的代码。看起来作者不知道计算机是如何工作的。”哇!似乎你并不知道格式化是怎么回事啊!我觉得那段代码没有什么问题! - mohamnag
1
@mohamnag:你说得对。我不知道为什么我写了这个...(7年前)。也许链接页面上的代码已经改变了。真的没有头绪,代码确实没问题。我修改了我的回答。 - Martijn Courteaux
1
撤回我之前的负评,以表达对你诚实的赞赏;-) - mohamnag

4

您可以使用 DatatypeConverter.printHexBinary(digiest) 来获取由32个十六进制数字表示的128位哈希值。下面是在Java中生成MD5哈希的完整代码片段,请点击此处

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.xml.bind.DatatypeConverter;

public class MD5HashGenerator 
{

public static void main(String args[]) throws NoSuchAlgorithmException
{
    String stringToHash = "MyJavaCode"; 
    MessageDigest messageDigest = MessageDigest.getInstance("MD5");
    messageDigest.update(stringToHash.getBytes());
    byte[] digiest = messageDigest.digest();
    String hashedOutput = DatatypeConverter.printHexBinary(digiest);
    System.out.println(hashedOutput);
}
}

1
我尝试了你上面的例子,MungPass(“java”)并得到一个32位字符串, 93f725a07423fe1c889f448b33d21f46。由于当你运行时前20个是正确的,我猜想你只是在打印输出中遗漏了某些内容?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接