Java MD5哈希显示垃圾字符

4

我写了一个简单的函数来将字符串转换为MD5,但输出结果中出现了奇怪的字符。我认为是某个字符编码出了问题。请问有人能指出我的错误吗?

public class App 
{   
public static void main(String[] args){
    String str = "helloWorldhelloWorldhelloWolrd";
    getHash(str);

}

public static void getHash(String str){
    try {
        byte[]  three = str.getBytes("UTF-8");
        MessageDigest   md = MessageDigest.getInstance("MD5");
        byte[] thedigest = md.digest(three);
        String  str1 = new String(thedigest,"UTF-8");
        System.err.println(str1);
    } catch (NoSuchAlgorithmException e) {

        e.printStackTrace();
    }catch (UnsupportedEncodingException e) {

        e.printStackTrace();
    }
}

}

输出: 这是我看到的内容。

                                n?)?????fC?7

2
如果您可以使用第三方库,Guava 可以在一行代码中使用 Hashing.md5().hashString(string, Charsets.UTF_8).toString() 获取十六进制编码的 MD5 哈希值。 - Louis Wasserman
2个回答

7
你需要将字节转换为十六进制字符串,而不是直接转换为字符串:
byte[] thedigest = md.digest(three);
StringBuilder buff = new StringBuilder();
for (byte b : theDigest) {
  String conversion = Integer.toString(b & 0xFF,16);
  while (conversion.length() < 2) {
    conversion = "0" + conversion;
  }
  buff.append(conversion);
}
String str1 = buff.toString();
System.err.println(str1);

2
这样做是行不通的。你必须考虑负字节,这意味着你必须执行 b & 0xFF,然后你还必须考虑填充,因为有些字节将被编码为一个字符而没有前导零。 - Louis Wasserman
这是我使用的代码:final BigInteger bigInt = new BigInteger(1, md.digest()); String.format("%032x", bigInt); - Jason Sperske
@LouisWasserman 负字节将采用二进制补码格式,对吧? - Chris Cooper
通过您的更改,我看到了这个6e-6329-647f-7f-22-47-42-5210661143-3837。 - javaMan
感谢Jason的评论。 - Miklos Krivan

2

您无法将摘要显示为字符串(因为它只是垃圾),您需要以某种方式转换字节,以便可以以人类可读的形式显示它们。我建议使用Base64编码器。

这里有另一个讨论如何将MD5转换为字符串的线程(链接)


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