关于c#:如何在不读取同一文件两次的情况下计算两个哈希值?

How can I compute two hashes without reading the same file twice?

我有一个程序将用于非常大的文件(当前测试数据是250GB)。我需要能够计算这些文件的MD5和SHA1哈希。当前,我的代码将流放到md5.create().computehash(流流流)中,然后对sha1执行相同的操作。据我所知,这些函数将4096字节块中的文件读取到哈希函数内部的缓冲区,直到流结束。

问题是,一个接一个做要花很长时间!在将新块读取到缓冲区之前,有没有任何方法可以将数据带到缓冲区并为两种算法提供缓冲区?

请详细解释,因为我不是一个有经验的编码员。


当然。您可以反复调用TransformBlock,然后在末尾调用TransformFinalBlock,然后使用Hash获取最终哈希。比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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)。