【发布时间】:2018-07-06 03:59:40
【问题描述】:
这是一个计算文件哈希值的函数。但我总是时不时得到错误的哈希码。
string filePath = @"G:\TV\movie.ts"; // about 10 GByte
private void Test()
{
for (int i = 0; i < 99; i++)
{
byte[] bytes;
try
{
var SHA256 = System.Security.Cryptography.SHA256.Create();
var MD5 = System.Security.Cryptography.MD5.Create();
var SHA512 = System.Security.Cryptography.SHA512.Create();
using (var stream = File.OpenRead(filePath))
{
stream.Position = 0;
bytes = MD5.ComputeHash(stream);
Debug.Print(i + ": " + BitConverter.ToString(bytes).Replace("-", ""));
stream.Position = 0;
bytes = SHA256.ComputeHash(stream);
Debug.Print(i + ": " + BitConverter.ToString(bytes).Replace("-", ""));
stream.Position = 0;
bytes = SHA512.ComputeHash(stream);
Debug.Print(i + ": " + BitConverter.ToString(bytes).Replace("-", ""));
}
MD5.Dispose();
SHA256.Dispose();
SHA512.Dispose();
}
catch (IOException e)
{
Debug.Print(e.ToString());
}
}
}
一个大文件(电影 ~10GB)的结果。 对于 MD5(短)和 SHA256(中),我将偏差标记为粗体。 当您查看 SHA512(长)结果时,您会看到从我执行测试的 8x 中,我得到 4x1B04E14AD6A0D1CC9D131D37D92C90146C118655B50935033A67BC0F436E9CAC424B569CCDB392D12B477DA751F30CD677023D78A55AA3CC97F8F8CD9F941D97 3xF9A6C6C61579FF989F17FB78DD23F1A4B6290588002EE58FB2C9427C75DD35D4745D15DB868CFCC94A49C9227E6C058FB89E862E50E8A06C527FC8C72EDCAFC7 1x1A3050206C8F3E94FC918F140215ADF2A9F463EAF083D421F5AF3FC450A634E9DF04C62889C3F295D504DDE34014CEF4A908C01D26770E250311816F77826B23
这表明,当它出错时,通常会导致相同的错误哈希。
所以问题是,为什么我会时不时地用每种算法得到错误的结果?
0: 920651841DF511BC45B51DABF76F08D8
0: ADA7EDB960A0EBB298E6BAB8FBF5E2C3D7D2E170B2C19B0B6432A469F2A398B7
0: 1B04E14AD6A0D1CC9D131D37D92C90146C118655B50935033A67BC0F436E9CAC424B569CCDB392D12B477DA751F30CD677023D78A55AA3CC97F8F8CD9F941D97
1: 920651841DF511BC45B51DABF76F08D8
1:ADA7EDB960A0EBB298E6BAB8FBF5E2C3D7D2E170B2C19B0B6432A469F2A398B7
1:1A3050206C8F3E94FC918F140215ADF2A9F463EAF083D421F5AF3FC450A634E9DF04C62889C3F295D504DDE34014CEF4A908C01D26770E250311816F77826B23
2: 920651841DF511BC45B51DABF76F08D8
2:ADA7EDB960A0EBB298E6BAB8FBF5E2C3D7D2E170B2C19B0B6432A469F2A398B7
2:1B04E14AD6A0D1CC9D131D37D92C90146C118655B50935033A67BC0F436E9CAC424B569CCDB392D12B477DA751F30CD677023D78A55AA3CC97F8F8CD9F941D97
3:944638B455C6C4DBF1B4149B16360C4E
3:ADA7EDB960A0EBB298E6BAB8FBF5E2C3D7D2E170B2C19B0B6432A469F2A398B7
3:F9A6C6C61579FF989F17FB78DD23F1A4B6290588002EE58FB2C9427C75DD35D4745D15DB868CFCC94A49C9227E6C058FB89E862E50E8A06C527FC8C72EDCAFC7
4: 920651841DF511BC45B51DABF76F08D8
4:ADA7EDB960A0EBB298E6BAB8FBF5E2C3D7D2E170B2C19B0B6432A469F2A398B7
4:1B04E14AD6A0D1CC9D131D37D92C90146C118655B50935033A67BC0F436E9CAC424B569CCDB392D12B477DA751F30CD677023D78A55AA3CC97F8F8CD9F941D97
5: 920651841DF511BC45B51DABF76F08D8
5:03DD7ADCA595F925E9226D1022D2FFB06F59710677E01472E4267E635DC4020A
5:F9A6C6C61579FF989F17FB78DD23F1A4B6290588002EE58FB2C9427C75DD35D4745D15DB868CFCC94A49C9227E6C058FB89E862E50E8A06C527FC8C72EDCAFC7
6: 920651841DF511BC45B51DABF76F08D8
6:ADA7EDB960A0EBB298E6BAB8FBF5E2C3D7D2E170B2C19B0B6432A469F2A398B7
6:1B04E14AD6A0D1CC9D131D37D92C90146C118655B50935033A67BC0F436E9CAC424B569CCDB392D12B477DA751F30CD677023D78A55AA3CC97F8F8CD9F941D97
7: 945F30E57094D2725B727D69F7BE7F4C
7: ADA7EDB960A0EBB298E6BAB8FBF5E2C3D7D2E170B2C19B0B6432A469F2A398B7
7:F9A6C6C61579FF989F17FB78DD23F1A4B6290588002EE58FB2C9427C75DD35D4745D15DB868CFCC94A49C9227E6C058FB89E862E50E8A06C527FC8C72EDCAFC7
【问题讨论】:
-
您的磁盘可能有问题...哈希算法是确定性的。相同的输入 == 相同的输出。
-
包含哈希的文本墙并没有真正增加问题。我们相信你,哈希值有时是不同的。
-
我真的不相信有故障的磁盘,因为您可以在任务管理器中看到该文件仅从磁盘加载了 1 次(磁盘活动 100% 有一段时间)。所有重复的文件读取都是从 RAM 中执行的。 Windows 会自动缓存它。从其他磁盘运行它时,我得到了相同的结果。 Vor 小文件高达几 MB,我从未见过这种情况发生。
-
我最初的想法是设置位置时流缓冲区没有被清除。但这是
StreamReader的问题(通过调用DiscardBufferedData()解决),而不是FileStream。所以我不确定。 -
为了减少这是框架/JIT 错误的可能性,请为每个哈希计算打开不同的流,而不是重置位置。另外,尝试在
cmd/PowerShell 循环中将可执行文件作为一个整体运行 99 次,而不是让它自己进行 99 次计算。此外,根据 xanatos,不要忽视硬件故障的可能性——单个 RAM 芯片中的单个故障位可以完全改变哈希值,而不会在实际应用程序中造成问题。