输入流中的MD5校验和

3

我正在尝试获取输入流的md5摘要,但我得到的字符串加密不正确。

我的md5字符串为:ä?E´]Õaá*TàŠöJ

而应该是:e48f0b45b45dd56102e12a54e08af64a

你能发现我做错了什么吗?这里是一个工作正常的程序:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class main {

public static void main(String[] args) throws IOException {

    byte[] fileContents = new byte[15 * 10000000];

    FileOutputStream out = new FileOutputStream("C:\\testFile");
    out.write(fileContents);
    out.close();

    File file = new File("C:\\testFile");
    FileInputStream fs = new FileInputStream(file);

    System.out.println(new String(getBytesOfMd5(fs)));

}

public static byte[] getBytesOfMd5(InputStream is) throws IOException {
    byte[] buffer = new byte[1024];
    MessageDigest complete = null;
    try {
        complete = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
        return null;
    }

    int numRead;
    do {
        numRead = is.read(buffer);
        if (numRead > 0) {
            complete.update(buffer, 0, numRead);
        }
    } while (numRead != -1);

    is.close();
    return complete.digest();
}
}

1
你只需要将字节数组转换成十六进制即可... 在javax.xml.DatatypeConverter中有一个合适的方法(printHexBinary)。 - Alnitak
另外,还要看一下DigestInputStream类。 - Alnitak
你说“加密”。MD5不是一种加密,而是一种哈希函数。加密可以被反转(使用密钥),但哈希不能被反转。确保哈希函数是你想要的。 - rossum
2个回答

4

digest()方法返回哈希值的字节表示。然后您试图直接将这些字节转换为字符串。

您想要的是将每个字节转换为两个十六进制数字。以下是代码:

byte[] hash = complete.digest();
StringBuilder sb = new StringBuilder();
for (byte b : hash)
  sb.append(String.format("%02x", b & 0xFF));
String hexHash = sb.toString();
System.out.println(hexHash);

直接使用java.util.Formatter比为每个字节使用String.format更好。 - VGR
@VGR,使用javax.xml.DatatypeConvert.printHexBinary会更好!这是一个标准的JDK函数... - Alnitak

1

你只需要将字节数组转换为十六进制:

import javax.xml.DatatypeConverter;

String hex = DatatypeConverter.printHexBinary(getBytesOfMd5(fs));

注意:您还可以使用DigestInputStream包装您的InputStream,以便在读取流时自动计算摘要。

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