检查两个图像文件是否相同..Checksum或Hash?

时间:2011-06-17 06:27:36

标签: java image-processing hash checksum integrity

我正在做一些图像处理代码,我从URL下载一些图像(作为BufferedImage)并将其传递给图像处理器。

我想避免多次将同一图像传递给图像处理器(因为图像处理操作成本很高)。图像的URL端点(如果它们是相同的图像)可能会有所不同,因此我可以通过URL来防止这种情况。所以我打算做一个校验和或哈希,以确定代码是否再次遇到相同的图像。

对于md5,我尝试了Fast MD5,它为图像生成了一个20K +字符长度的十六进制校验和值(一些样本)。显然,在数据库存储方面存储这个20K +字符哈希是一个问题。因此我尝试了CRC32(来自java.util.zip.CRC32)。它确实产生了比哈希小得多的长度校验和。

我确实理解校验和和哈希用于不同的目的。出于上述目的,我可以使用CRC32吗?它会解决目的还是我必须尝试比这两个更多的东西?

谢谢, 阿比

2 个答案:

答案 0 :(得分:5)

CRC与MD5之间的区别在于,篡改文件以匹配“目标”MD5比篡改它以匹配“目标”校验和更困难。由于这对您的程序来说似乎不是问题,因此您使用哪种方法无关紧要。也许MD5可能会更加耗费CPU,但我不知道这种不同是否重要。

主要问题应该是摘要的字节数。

如果您在整数中进行校验和将意味着,对于2K大小的文件,您将2 ^ 2048个组合拟合为2 ^ 32个组合 - >对于每个CRC值,您将有2 ^ 64个与之匹配的可能文件。如果你有一个128位的MD5,那么你有2 ^ 16个可能的冲突。

您计算的代码越大,碰撞可能性越小(假设计算的代码均匀分布),因此比较更安全。

无论如何,为了尽量减少可能的错误,我认为第一个分类应该是使用文件大小...首先比较文件大小,如果它们匹配则比较校验和/散列。

答案 1 :(得分:1)

校验和和散列基本相同。您应该能够计算任何类型的哈希。常规MD5通常就足够了。如果你愿意,你可以存储大小和md5哈希(我认为这是16个字节)。

如果两个文件的大小不同,则它们是不同的文件。您甚至不需要计算数据的哈希值。如果您不太可能有多个重复文件,并且文件类型较大(例如,使用相机拍摄的JPG图片),则此优化可能会为您节省大量时间。

如果两个或多个文件具有相同的大小,则可以计算哈希值并进行比较。

如果两个哈希值相同,您可以比较实际数据,看看它是否完全不同。这非常非常不可能,但在理论上是可行的。散列越大(md5为16字节,而CR32仅为4),两个不同文件具有相同散列的可能性越小。 虽然这只需要10分钟的编程来执行这项额外的检查,所以我会说:比抱歉更安全。 :)

要进一步优化此功能,如果两个文件的大小完全相同,则只需比较它们的数据即可。您无论如何都需要读取文件以计算它们的哈希值,所以如果它们是具有该特定大小的唯一两个,为什么不直接比较它们。