如何通过MD5比较图像?

8

这个方法比较的是图像的像素值吗?我猜测它不起作用,因为它们的大小不同,但如果它们是相同的,但格式不同呢?例如,我截了两张屏幕截图,一张保存为.jpg,另一张保存为.gif


2
哈希将允许您仅比较32位长的哈希值,这比直接比较图像本身要快得多。 - Your Common Sense
9个回答

22

MD5哈希值是基于二进制数据计算的,因此不同格式的文件将具有完全不同的二进制数据。

所以,要使MD5哈希值匹配,它们必须是相同的文件。 (在一些边缘情况下可能会有例外,详情请参考维基百科

事实上,这是司法执法机构寻找被视为违禁品的数据(就图像而言)的一种方法。


1
如果我有一张图片并使用JPEG格式进行压缩,然后在10台不同的机器上重复此过程10次,那么压缩后的图像是否始终具有相同的MD5值?JPEG压缩是否是确定性的? - Mehdi

10

这是一个MD5校验和——通常在下载文件时会遇到。如果下载的文件的MD5与提供者给出的MD5匹配,则文件传输成功。http://en.wikipedia.org/wiki/Checksum 如果两个文件之间有一位不同,那么生成的哈希值将完全不同。

由于JPG和GIF之间编码的差异,它们的MD5哈希值也不相同。


1
这解释了MD5,但并没有回答他实际的问题,即是否可以比较不同的图像格式。 - KyleWpppd
1
这句话的意思是:“如果两个文件之间只有一个比特位不同,那么它们的哈希值也会完全不同。”但我会改变答案。 - Gazler

5

md5 是一种哈希算法,所以它不会比较图像,而是比较数据。您输入的数据可以是几乎任何东西,例如文件的内容。然后根据这些内容输出一个哈希字符串,这个字符串是文件的原始数据。

因此,在将图像传递到 md5 时,您实际上并不会比较图像,而是比较图像的原始数据。哈希算法只知道这些原始数据,并不了解其他内容,因此同一截图的jpggif(或任何其他图像格式)永远不会相同。

即使您比较解码后的图像,它也不会输出相同的哈希值,而会有一些肉眼看不见的小差异(这取决于使用的压缩量)。当比较无损编码图像已解码数据时,情况可能有所不同,但我在这方面不太清楚。

请参阅维基百科文章以获取有关哈希函数的更详细解释和技术背景。


3

当你查看原始字节时,.jpg文件以“JFIF”开头,.gif文件以“GIF”开头。换句话说,比较两种不同格式的“相同图像”的磁盘上的字节几乎肯定会产生两个不同的MD5哈希值,因为文件内容不同,即使实际的图像是“相同的图片”。

要进行基于哈希的图像比较,必须使用相同格式比较两个图像。如果将它们转换为(例如).bmp,则非常难以生成相同的图像,其中一个是.jpg,另一个是.gif。它们可能是相同的文件格式,但.gif的内部要求(8位、RLE/LZW无损压缩)与.jpg的内部要求(24位、有损离散余弦变换压缩)意味着从这两个源图像中获得相同的.bmp几乎是不可能的。


2

如果您正在比较哈希值,则两个图像的每个字节都必须匹配,它们不能使用不同的压缩格式或“看起来相同”。它们必须完全相同。


1

MD5是一种哈希算法。它是从一堆数据中计算出来的代码 - 任何数据都可以。

MD5肯定不是唯一的,但两个不同图像具有完全相同代码的机会非常小。因此,您可以通过从每个图像计算MD5代码并比较代码来比较图像。


我想补充一点,我不会完全信任这种方法。任何发现的重复图像仍应通过其确切内容进行检查。 - GolezTrol
1
这是不必要的,甚至有点过于谨慎了。请参考以下链接中的数学原理:https://dev59.com/gUbRa4cB1Zd3GeqP1IfB - Piskvor left the building
是的,可能吧。但我学到了你永远不能确定。如果两个MD5确实匹配并且其他简单检查(如文件大小、像素大小或元信息)也匹配,则可能只需要3行代码来进行二进制比较。这将使您无需对每个文件进行哈希处理。只有具有相同大小和元信息的文件需要进行哈希处理。我认为这可能会给您更好的优化(特别是在比较较大的图像,如照片时),而不仅仅是对您拥有的每个图像进行哈希处理并比较这些哈希值。但当然这取决于情况。 - GolezTrol
我现在明白了,这不是关于文件,而是关于屏幕截图。这对我来说没有什么用处。GIF具有有限的色深,而JPEG由于压缩算法而导致质量损失。一个jpg的屏幕截图和一个gif的屏幕截图几乎不可能得到完全相同的图像。 - GolezTrol
在这种情况下,最好使用给定的容差逐像素匹配。超出该容差的像素也可以计算在内。这将导致两个图像之间的某种“距离”。大小相同且仅有小距离的图像可能显示相同的图像。 - GolezTrol

1

正如其他帖子中所指出的那样,您不能使用MD5摘要进行比较。但是,您可以以不同的方式比较图像,并且它将告诉您它们的相似性,而不管图像类型甚至大小。您可以使用libPuzzle。

http://libpuzzle.pureftpd.org/project/libpuzzle

这是一个非常好用的图像比较库,功能非常强大。


感谢您提供有关libpuzzle的提示,我们使用PHP,但似乎该库目前更适用于*nix系统,不支持Windows,因此对我们来说效果较差。此外,我还想指出,对于那些想要更完整的图像比较解决方案(既是库又是终端用户工具)的人,请查看Sikuli.org。该工具也是跨平台的。 - David

0

这仍然不会起作用。任何图像都包含头部部分和二进制图像缓冲区。在上述情况下: 1. .jpg和.gif之间的头部将不同,导致不同的md5校验和 2. 由于像.jpg格式使用的图像压缩方式不同,图像缓冲区本身可能也会不同。


0

md5sum 是一种用于验证文件完整性的工具,因为对文件的任何更改都会导致其 MD5 哈希值发生变化。

最常见的情况是,md5sum 用于验证文件在传输过程中没有发生更改,也没有磁盘错误或非恶意干扰。 md5sum 程序包含在大多数类 Unix 操作系统或兼容层(如 Cygwin)中。

因此它不能用于比较图像。

在图像上运行 md5sum 将基于图像原始数据生成 md5 哈希值。这些图像的哈希字符串输出将不同,因为图像格式不同,例如 GIF 和 JPEG。

此外,如果您比较这些图像的大小,它们也不会相同。通常情况下,GIF 图像可能比 JPEG 文件更大,这意味着 MD5 哈希值 字符串根本不匹配。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接