【问题标题】:How can I compute two hashes without reading the same file twice?如何在不两次读取同一个文件的情况下计算两个哈希?
【发布时间】:2013-02-01 00:12:27
【问题描述】:

我有一个程序将用于非常大的文件(当前测试数据为 250GB)。我需要能够计算这些文件的 MD5 和 SHA1 哈希值。目前,我的代码将流放入 MD5.Create().ComputeHash(Stream stream),然后对 SHA1 也是如此。据我所知,这些以 4096 字节块的形式将文件读取到哈希函数内部的缓冲区中,直到流结束。

问题是,一个接一个地做这个需要很长时间!有什么方法可以在将新块读入缓冲区之前将数据放入缓冲区并为两种算法提供缓冲区?

请详细解释,因为我不是经验丰富的编码员。

【问题讨论】:

标签: c# hash md5 sha1


【解决方案1】:

当然。你可以反复调用TransformBlock,最后再调用TransformFinalBlock,再使用Hash得到最终的hash。所以像:

using (var md5 = MD5.Create()) // Or MD5Cng.Create
using (var sha1 = SHA1.Create()) // Or SHA1Cng.Create
using (var input = File.OpenRead("file.data"))
{
    byte[] buffer = new byte[8192];
    int bytesRead;
    while ((bytesRead = input.Read(buffer, 0, buffer.Length()) > 0)
    {
        md5.TransformBlock(buffer, 0, bytesRead, buffer, 0);
        sha1.TransformBlock(buffer, 0, bytesRead, buffer, 0);
    }
    // We have to call TransformFinalBlock, but we don't have any
    // more data - just provide 0 bytes.
    md5.TransformFinalBlock(buffer, 0, 0, buffer, 0);
    sha1.TransformFinalBlock(buffer, 0, 0, buffer, 0);

    byte[] md5Hash = md5.Hash;
    byte[] sha1Hash = sha1.Hash;
}

MD5Cng.CreateSHA1Cng.Create 调用将围绕本机实现创建包装器,这可能比 MD5.CreateSHA1.Create 返回的实现更快,但可移植性稍差(例如对于 PCL) .

【讨论】:

  • 完美 :) 我刚刚对其进行了测试,输出与我的参考工具(FTK Imager)产生的哈希一致,所以我很高兴!
  • 如果您一次计算两个哈希值,那是因为您希望代码运行得快。因此,假设您不支持 Windows XP,您可能应该使用 MD5Cng.Create() 和 SHA1Cng.Create()。见:stackoverflow.com/questions/5341874/…
  • @0xdabbad00:还假设您对可移植类库、商店应用程序等不感兴趣……但我会添加注释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-09
  • 2012-12-31
  • 2010-11-17
  • 2010-11-19
  • 2016-08-14
  • 2023-03-03
相关资源
最近更新 更多