StackOverflow题目“Calclate MD5 checksum for a file”中引用的代码提供了一种基于文件获取校验和的简单方法。这是可行的,但是通过测试,我发现更改文件元数据也会导致校验和更改。我想这是有道理的,因为从技术上讲,具有不同元数据的副本是不同的文件。该代码:
using (var md5 = MD5.Create())
{
using (var stream = File.OpenRead(filename))
{
return md5.ComputeHash(stream);
}
}
当图像在工作中通过各种系统时,图像元数据会因各种原因而添加和更改,这意味着文件校验和不能用于查找系统中的重复项。
我需要的是一种基于映像本身而不是映像 * 文件 * 生成校验和的方法。
我尝试解决此问题,结果生成了以下代码:
using (var md5 = MD5.Create())
{
using (var stream = new MemoryStream())
{
using (Image image = Image.FromFile(fileName))
{
image.Save(stream, image.RawFormat);
var hash = md5.ComputeHash(stream);
var convertedHash = BitConverter.ToString(hash).Replace("-", String.Empty).ToLowerInvariant();
return convertedHash;
}
}
}
这对我来说似乎很简单,代码运行没有错误,但是无论我输入什么图像,我都得到相同的校验和,所以有些地方是错的。我只是似乎不能确定为什么会发生这种行为。任何输入或知识都非常感谢。为什么这会为任何图像生成相同的校验和?我做错了什么或遗漏了什么?
(Edit:为了清楚起见,我知道图像数据本身必须完全相同才能生成相同的校验和;这就是我所需要的。iIndiee.,我不想找到相似或非常相似的图像等)
2条答案
按热度按时间2lpgd9681#
尝试将流位置重置为起始位置:
在
Save()
之后和ComputeHash()
之前执行此操作。fafcakar2#
您的问题是由以下事实引起的:在写入流之后,在阅读流之前没有重置流的位置,因此每次都得到相同的哈希值。
您可以通过传入一个新流来轻松验证这一点:
这对我来说返回
d41d8cd98f00b204e9800998ecf8427e
,与我在加载文件而不倒带流时得到的结果相同。如果你重置了位置,你会得到每个文件不同的哈希值: