2013-02-15 54 views
4

我有一个程序将用于非常大的文件(当前测试数据为250GB)。我需要能够为这些文件计算MD5和SHA1散列值。目前,我的代码将数据流放入MD5.Create()。ComputeHash(数据流数据流)中,然后对SHA1执行相同操作。据我所知,这些文件以4096字节块的形式读取到散列函数内部的缓冲区,直到流结束。如何在不读取同一个文件两次的情况下计算两个哈希值?

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

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

+0

将其逐段读取并将数据提供给您自己的摘要算法串联 – sehe 2013-02-15 22:41:42

+0

检查:http://stackoverflow.com/questions/14610850/how-to-get-file-both-md5-and-sha1-checksum- at-the-same-time-when-upload-a-new-fi(java) – PunKeel 2013-02-15 22:42:33

+0

http://stackoverflow.com/questions/7832440/is-hashalgorithm-computehash-stateful – 2013-02-15 22:43:18

回答

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; 
} 

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

+0

@GregS:所以它 - 修好了,谢谢。 – 2013-02-16 07:57:07

+0

完美:)我只是测试它,输出与我的参考工具(FTK Imager)产生的散列一致,所以我都很高兴! – 2013-02-16 16:45:57

+0

如果您一次计算两个哈希值,那是因为您希望代码运行得很快。因此,您可能应该使用MD5Cng.Create()和SHA1Cng.Create(),假设您不支持Windows XP。请参阅:http://stackoverflow.com/questions/5341874/which-one-to-use-managed-vs-nonmanaged-hashing-algorithms – 0xdabbad00 2014-10-15 02:22:35

相关问题