我需要计算相当大的文件(千兆字节)的校验和 . 这可以使用以下方法完成:
private byte[] calcHash(string file)
{
System.Security.Cryptography.HashAlgorithm ha = System.Security.Cryptography.MD5.Create();
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
byte[] hash = ha.ComputeHash(fs);
fs.Close();
return hash;
}
但是,文件通常是以缓冲方式预先写入的(比如一次写入32mb) . 我确信我看到了一个覆盖哈希函数,它允许我在写入的同时计算MD5(或其他)哈希,即:计算一个缓冲区的哈希值,然后将得到的哈希值输入到下一个迭代中 .
像这样的东西:(伪代码)
byte [] hash = new byte [] { 0,0,0,0,0,0,0,0 };
while(!eof)
{
buffer = readFromSourceFile();
writefile(buffer);
hash = calchash(buffer, hash);
}
hash现在通过在整个文件上运行calcHash函数来实现 .
现在,我无法在.Net 3.5框架中找到任何覆盖,我在做什么?它从来没有存在过,或者我只是在搜索时很糟糕?同时进行写入和校验和计算的原因是因为大文件才有意义 .
5 回答
您使用
TransformBlock
和TransformFinalBlock
方法以块的形式处理数据 .注意:它(至少与MD5提供程序一样)可以将所有块发送到
TransformBlock
,然后将空块发送到TransformFinalBlock
以完成该过程 .我喜欢上面的答案,但为了完整起见,并且是一个更通用的解决方案,请参阅
CryptoStream
类 . 如果您已经在处理流,则很容易将流包装在CryptoStream
中,并将HashAlgorithm
作为ICryptoTransform
参数传递 .您可能必须在获取哈希值之前关闭流(因此
HashAlgorithm
知道它已完成) .似乎你可以使用
TransformBlock
/TransformFinalBlock
,如下例所示:Displaying progress updates when hashing large filesHash算法有望处理这种情况,通常用3个函数实现:
hash_init()
- 调用分配资源并开始哈希 .hash_update()
- 在新数据到达时调用 .hash_final()
- 完成计算和免费资源 .查看http://www.openssl.org/docs/crypto/md5.html或http://www.openssl.org/docs/crypto/sha.html,了解C中的标准示例;我相信你的平台有类似的库 .
我只需要做类似的事情,但想要异步读取文件 . 它正在使用TransformBlock和TransformFinalBlock,并给我与Azure一致的答案,所以我认为这是正确的!