4

识别二进制文件的最有效方法是什么?我想从二进制文件中提取某种签名并用它与其他文件进行比较。

蛮力方法是使用整个文件作为签名,这将花费太长时间和太多内存。我正在寻找一种更聪明的方法来解决这个问题,并且我愿意为性能牺牲一点准确性(但不要太多,嗯)。

(虽然首选 Java 代码示例,但鼓励与语言无关的答案)

编辑:扫描整个文件以创建哈希的缺点是文件越大,所需的时间越长。由于哈希无论如何都不会是唯一的,我想知道是否有更有效的方法(即:来自均匀分布的字节采样的哈希)。

4

4 回答 4

12

我发现对这类事情有效的一种方法是计算两个 SHA-1 哈希值。一个用于文件中的第一个块(我任意选择 512 字节作为块大小),一个用于整个文件。然后我将两个哈希值与文件大小一起存储。当我需要识别文件时,我会首先比较文件长度。如果长度匹配,那么我将比较第一个块的哈希,如果匹配,我将比较整个文件的哈希。前两个测试迅速清除了许多不匹配的文件。

于 2010-08-14T12:43:45.117 回答
3

这就是哈希的用途。请参阅MessageDigest

请注意,如果您的文件太大而无法在内存中读取,那没关系,因为您可以将文件的块提供给散列函数。例如,MD5 和 SHA1 可以采用 512 位的块。

此外,具有相同哈希的两个文件不一定相同(尽管它们不同的情况很少见),但两个相同的文件必然具有相同的哈希。

于 2010-08-14T12:11:01.297 回答
2

通常的答案是使用 MD5,但我想建议在现代应用程序中使用 MD5 的冲突太多:http ://www.mscs.dal.ca/~selinger/md5collision/

SHA-1 在十多年前取代了 MD5。

NIST 在 2005 年建议在 2010 年之前使用 SHA-2 代替 SHA-1,因为已经开展工作以证明 SHA-1 的简化变体中的冲突。(这是非常好的远见,因为现在已知需要 2^51 的工作才能找到碰撞,而理想情况下应该需要 2^80 的工作才能找到碰撞。)

因此,请根据您要执行的操作以及您可能需要与哪些其他程序进行互操作,在 MD5(请不要)、SHA-1(我理解,但我们可以做得更好)和 SHA 中进行选择-2(选我!选我!)。

于 2010-08-14T12:27:49.553 回答
0

您是否考虑使用标头标识。如果你能以这种方式设计你的文件,这将是快速和可靠的。使用一个字节,您可以区分 255 种文件类型;)

于 2010-08-14T12:34:35.123 回答