【问题标题】:C# MD5 Hash inconsistent on files over 2GBC# MD5 Hash 在超过 2GB 的文件上不一致
【发布时间】:2021-07-07 12:34:06
【问题描述】:

我正在编写一个 c# 应用程序以使用其 V3 API 下载 Google Drive 文件,并检查 Google 提供的 MD5 哈希以确认下载。一切进展顺利,应用程序正在运行,除了当文件大小超过 2GB 时,检查 MD5 哈希的失败率高达 75% 以上。有些工作,大多数没有。

如果我使用第 3 方 MD5 实用程序进行检查,它会提供正确的哈希值(与 Google Drive 相同)。我尝试单独下载到我的应用程序(即通过浏览器),以防我的应用程序在下载时做一些奇怪的事情,但是在通过我的应用程序检查 md5 哈希时也会失败。所以这显然是在我的尽头发生的事情。

我正在使用 c# System.Security.MD5 库,使用 TransformBlock 和 TransformFinalBlock。我尝试了不同的缓冲区大小,只是为了好玩,但没有运气。我也尝试了完整的文件 - ComputeHash(Stream) - 但这也失败了)。

我唯一能看到的(完全抓住稻草)是 inputOffset 和 inputCount 参数是 int,如果这些函数有一个内部的“总文件”,这 可能可以解释 2GB 的限制size" 或类似的,它也是一个 int(32 位有符号 - 假定)。

我注意到的另一件事是,该进程将每 8-25% 暂停一次,在继续之前的几分钟内,任何地方都没有 CPU、磁盘、RAM、垃圾收集或其他活动。当它“运行”时,我看到了磁盘、CPU 等,正如预期的那样,并且进展相当迅速。这种暂停似乎不会影响最终哈希是否“成功”,但可能是相关的(我在 2GB 以下的大文件上也看到了它)。

有谁知道这是否是一个问题?我见过几个人就大文件哈希的问题提出类似的问题,但没有帮助的答案是哈希应该总是相同的......是的,他们应该,但看起来他们可能不是。最奇怪的是偶尔会在大文件上使用哈希。

下面是代码的简化(错误检查、进度报告等,为了快速阅读而删除 - 是的,我也尝试过这个简化的代码 - 同样的问题)。不是最干净的,但它可以工作(除了> 2GB的文件)。提前感谢您提供有关该问题的任何建议或知识。

            int buffersize = 65536;
            using (var md5 = MD5.Create())
            {
                using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, buffersize))
                {
                    var block = new byte[buffersize];
                    int length = 0;
                    Int64 filesize = stream.Length;
                    Int64 bytesread = 0;
                    length = stream.Read(block, 0, buffersize);
                    bytesread += length;
                    while (length == block.Length)
                    {
                        md5.TransformBlock(block, 0, length, null, 0);
                        length = stream.Read(block, 0, buffersize);
                        bytesread += length;
                    }
                    md5.TransformFinalBlock(block, 0, length);
                    bytesread += length;
                }
                var hash = md5.Hash;
                return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();

【问题讨论】:

  • 看来这些都被批准了。 Calculating Md5 Hash of Big Files,How to compute Hash of a large file using a Hash Function (SHA or MD5)?,Computing MD5SUM of large files in C#除此之外,试试把程序的运行模式改成32bit/64bit?或者为什么不下载整个文件后尝试 MD5 哈希计算?
  • @kunif 下载后我正在检查。其他是该主题的变体。我将尝试将构建显式设置为 64 位并查看。
  • @kunif - 感谢您的建议。我尝试明确设置为 64 位,但没有任何变化。 :(
  • 如果是这样,为什么不向 Microsoft 和 Google 报告问题?
  • @kunif,我希望有人会看到我所做的错误/愚蠢的事情,这可以解释这一点。考虑到将成功使用 MD5 库的数以千计的开发人员和数以百万计的人,似乎世界上只有我一个人不太可能发现一个错误——我只是不是一个优秀的程序员。

标签: c# google-drive-api md5 large-files


【解决方案1】:

出于绝对未知的原因,它现在可以工作了。尽我所能猜测(这完全是理论上的,不应该发生),我正在研究应用程序的其他部分,这改变了某些东西的位置以避免出现任何错误......

由于未知原因,它仍然在这里和那里暂停,但哈希现在可以正确返回(应该匹配,不应该匹配)。

【讨论】:

  • 我仍然很想知道任何关于最初可能出错的理论......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-04
  • 1970-01-01
  • 2011-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-21
相关资源
最近更新 更多