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

Joa*_*wis 4 c# hash md5 sha1

我有一个程序,将用于非常大的文件(当前测试数据是250GB).我需要能够为这些文件计算MD5和SHA1哈希值.目前我的代码将流丢弃到MD5.Create().ComputeHash(Stream stream),然后是SHA1的相同内容.据我所知,这些文件以4096字节块的形式读取到散列函数内部的缓冲区,直到流的末尾.

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

由于我不是一位经验丰富的编码员,请详细解释.

Jon*_*eet 10

当然.您可以TransformBlock重复调用,然后TransformFinalBlock在最后使用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;
}
Run Code Online (Sandbox Code Playgroud)

MD5Cng.CreateSHA1Cng.Create调用将创建一个围绕本地实现这可能是比返回实现更快的包装MD5.CreateSHA1.Create,但是这将是便携式的(例如用于PCLS)少一点.