8

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

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

对于 md5 我尝试了Fast MD5,它为图像生成了一个 20K+ 字符长度的十六进制校验和值(一些示例)。显然,当涉及到数据库存储时,存储这个 20K+ 字符散列将是一个问题。因此我尝试了 CRC32(来自 java.util.zip.CRC32)。它确实生成了比散列更小的长度校验和。

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

谢谢,阿比

4

2 回答 2

5

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

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

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

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

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

于 2011-06-17T06:52:50.193 回答
1

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

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

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

如果两个哈希值相同,您可以比较实际数据,看看这是否不同。这是非常非常不可能的,但理论上是可能的。您的哈希值越大(md5 为 16 个字节,而 CR32 只有 4 个字节),两个不同文件具有相同哈希值的可能性就越小。不过,执行这个额外的检查只需要 10 分钟的编程时间,所以我想说:安全总比抱歉好。:)

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

于 2011-06-17T06:52:35.567 回答