0

尝试检查文件的 MD5 哈希时出现错误。

文件 notice.txt 包含以下内容:

My name is sanjay yadav . i am in btech computer science .>>

当我通过onlineMD5.com在线查看时,它给出的 MD5 为:90F450C33FAC09630D344CBA9BF80471.

我的程序输出是:

My name is sanjay yadav . i am in btech computer science .
Read 58 bytes
d41d8cd98f00b204e9800998ecf8427e

这是我的代码:

import java.io.*;
import java.math.BigInteger;
import java.security.DigestException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MsgDgt {
    public static void main(String[] args) throws IOException, DigestException, NoSuchAlgorithmException {

        FileInputStream inputstream = null;
        byte[] mybyte = new byte[1024];

        inputstream = new FileInputStream("e://notice.txt");
        int total = 0;
        int nRead = 0;
        MessageDigest md = MessageDigest.getInstance("MD5");
        while ((nRead = inputstream.read(mybyte)) != -1) {
            System.out.println(new String(mybyte));
            total += nRead;
            md.update(mybyte, 0, nRead);
        }

        System.out.println("Read " + total + " bytes");
        md.digest();
        System.out.println(new BigInteger(1, md.digest()).toString(16));
    }
}
4

2 回答 2

1

您的代码中有一个错误,相信在线工具给出了错误的答案。在这里,您当前正在计算摘要两次:

md.digest();
System.out.println(new BigInteger(1, md.digest()).toString(16));

每次调用时digest(),它都会重置内部状态。您应该删除对digest(). 然后将其作为摘要留给您:

2f4c6a40682161e5b01c24d5aa896da0

这与我从 C# 得到的结果相同,我相信它是正确的。我不知道为什么在线检查器给出的结果不正确。(如果你把它放到同一个站点的文本部分,它会给出正确的结果。)

不过,您的代码还有其他几点:

  • 将字节转换为字符串时,您当前正在使用平台默认编码。我强烈反对你这样做。
  • 您当前正在将整个缓冲区转换为字符串,而不仅仅是您读取的位。
  • 我不喜欢BigInteger将二进制数据转换为十六进制。您可能需要用 0 填充它,这基本上不是该类的设计目的。使用专用的十六进制转换类,例如来自 Apache Commons Codec(或为此目的提供独立类的各种 Stack Overflow 答案)。
  • 您没有关闭输入流。你应该在一个finally块中这样做,或者在 Java 7 中使用 try-with-resources 语句。
于 2013-07-02T06:19:33.483 回答
0

我使用这个功能:

public static String md5Hash(File file) {
    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        InputStream is = new FileInputStream(file);
        byte[] buffer = new byte[1024];

        try {
            is = new DigestInputStream(is, md);

            while (is.read(buffer) != -1) { }
        } finally {
            is.close();
        }

        byte[] digest = md.digest();

        BigInteger bigInt = new BigInteger(1, digest);
        String output = bigInt.toString(16);
        while (output.length() < 32) {
            output = "0" + output;
        }

        return output;
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return null;
}
于 2013-07-02T06:06:10.160 回答