在我的 2 TB 硬盘存储图像中查找重复项的过程中,我对 fslint 和 fslint-gui 工具的长时间运行感到惊讶。
因此,我分析了核心工具findup的内部结构,该工具使用超长管道实现为编写得非常好的和文档化的 shell 脚本。本质上它基于查找和散列(md5 和 SHA1)。作者表示它比我无法相信的任何其他替代方案都快。所以我发现检测重复文件的主题很快滑向散列和比较散列,在我看来这不是最好和最快的方法。
所以通常的算法似乎是这样工作的:
有时通过首先使用具有更高冲突概率的更快哈希算法(如 md5)来提高速度,然后如果哈希相同,则使用第二个更慢但更少类似碰撞的算法来证明重复项。另一个改进是首先只散列一小块以整理出完全不同的文件。
所以我认为这个方案在两个不同的方面被打破:
我发现一个(Windows)应用程序通过不使用这种常见的散列方案来说明速度很快。
我的想法和意见完全错误吗?
[更新]
似乎有人认为散列可能比比较更快。但这似乎是对“哈希表加速事物”的一般使用的误解。但是要生成文件的哈希,第一次文件需要逐字节读取。因此,一方面有逐字节比较,它只比较每个重复候选函数的这么多字节,直到第一个不同的位置。并且有一个哈希函数,它从这么多字节中生成一个 ID - 如果前 10k 是相同的,可以说是 1 TB 的前 10k 字节或完整 TB。因此,假设我通常没有准备好计算并自动更新的所有文件哈希表,我需要计算哈希并读取重复候选的每个字节。逐字节比较不'
[更新2]
我得到了第一个答案,它再次朝着这个方向发展:“哈希通常是一个好主意”,因此(不是那么错误)试图通过(恕我直言)错误的论点来合理化哈希的使用。“哈希更好或更快,因为您可以稍后重用它们”不是问题。“假设许多(比如 n 个)文件具有相同的大小,要找出哪些是重复的,您需要进行 n * (n-1) / 2 次比较以对它们进行成对测试。使用强哈希,你只需要对它们每个散列一次,总共给你 n 个散列。” 也偏向于哈希和错误(恕我直言)。为什么可以' t 我只是从每个相同大小的文件中读取一个块并在内存中进行比较?如果我必须比较 100 个文件,我会打开 100 个文件句柄并从每个文件句柄并行读取一个块,然后在内存中进行比较。这比用这 100 个文件更新一个或多个复杂的慢哈希算法要快得多。
[更新3]
鉴于对“人们应该始终使用哈希函数,因为它们非常好!”的巨大偏见!我通读了一些关于哈希质量的 SO 问题,例如: 哪种哈希算法最适合唯一性和速度?由于糟糕的设计和生日悖论,常见的哈希函数比我们认为的更经常产生冲突。测试集包含:“216,553 个英文单词的列表(小写),数字“1”到“216553”(想想邮政编码,以及一个糟糕的哈希如何摧毁 msn.com)和 216,553 个“随机”(即类型4 uuid) …