提高SHA-1 ComputeHash的性能

Bru*_*ams 6 .net c# performance

我正在使用以下代码来执行文件的校验和工作正常.但是当我为一个大文件生成哈希值时,比如2 GB,它很慢.如何提高此代码的性能?

fs = new FileStream(txtFile.Text, FileMode.Open);
        formatted = string.Empty;
        using (SHA1Managed sha1 = new SHA1Managed())
        {
            byte[] hash = sha1.ComputeHash(fs);

            foreach (byte b in hash)
            {
                formatted += b.ToString("X2");
            }
        }
        fs.Close();
Run Code Online (Sandbox Code Playgroud)

更新:

系统:

操作系统:Win 7 64位,CPU:I5 750,RAM:4GB,HDD:7200rpm

测试:

Test1 = 59.895秒

Test2 = 59.94秒

Jon*_*nna 3

第一个问题是您需要这个校验和的目的。如果您不需要加密属性,那么可以使用非加密哈希,或者加密安全性较低的哈希(MD5 被“破坏”并不妨碍它成为一个好的哈希,对于某些用途来说也仍然足够强大)可能会更加高效。您可以通过读取数据的子集来创建自己的散列(我建议使该子集在底层文件的 4096 字节块中工作,因为这将与 SHA1Managed 使用的缓冲区大小相匹配,并且允许比如果你确实说每个 X 字节代表 X 的某个值,你就会这样做。

编辑:一个赞成票提醒我这个答案,也提醒我,我写了SpookilySharp,它提供了高性能的 32 位、64 位和 128 位哈希值,这些哈希值不是加密的,但适合提供针对错误、存储等的校验和(这又提醒我应该更新它以支持.NET Core)。

当然,如果您希望文件的 SHA-1 与其他内容进行互操作,您就会陷入困境。

我会尝试不同的缓冲区大小,因为增加文件流缓冲区的大小可以提高速度,但代价是额外的内存。我建议使用 4096 的整数倍(顺便说一句,4096 是默认值),因为 SHA1Managed 会一次请求 4096 个块,这样就不会出现任何一个 FileStream 返回少于最多请求的情况(允许,但有时次优)或一次执行多个副本。