【发布时间】: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