生成校验和函数的变体以最小化冲突

时间:2013-09-29 13:36:17

标签: python diff md5 hash-function adler32

我的目标是有效地执行目录树的详尽差异。给定一组文件F,我必须计算等价类EQV = [F₁, F₂, F₃, ... Fₙ],使fⱼ, fₖ ∈ EQV[i] iff (fⱼ is identical to fₖ) for all i, j, k

我的一般方法是从一个包含所有初始文件EQV₀ = [[f₁, f₂, ..., fₙ]]的大类开始,然后反复将其拆分为更精确的类EQV₁EQV₂ ... {{1基于一些EQVₘ₋₁启发式算法,例如,文件大小,校验和函数1,校验和2.在应用了所有m启发式算法(m)之后,所有的成对差异必须在EQVₘ₋₁中的每个类中创建文件。因为最后一步是EQVₘ₋₁中每个类的二次方,即

EQVₘ₋₁

并且如果每个m分割都是在线性时间内完成的话,可能会成为我算法的瓶颈,我的目标是使O(sum(n² for n in map(len, EQVₘ₋₁)) ) 尽可能平坦。

我希望能够访问各种好的哈希函数,以便最大限度地减少EQVₘ₋₁上的冲突。我目前的想法是使用一些库提供的校验和功能,例如adler,并通过简单地将其应用于文件中的不同起始字节来生成它的变体。另一个是首先应用快速哈希函数,例如adler,然后是更昂贵的函数,例如md5,仅适用于仍然太大的类。

考虑到我只能在一次读取该文件时计算给定文件的所有哈希值,我怎么能计算出各种哈希值来帮助我区分不同的文件呢?

或者,python中可用的哈希函数列表中有哪些不是加密安全的?

编辑: 另一个想法似乎是使用基于一组固定随机生成的输入的“rabin指纹”。这有意义吗? http://en.wikipedia.org/wiki/Rabin_fingerprint

1 个答案:

答案 0 :(得分:1)

我建议先使用adler32, then crc32。可能有许多非常短的文件具有相同的adler32,但不同的crc32。实际上,您可以考虑在第一遍中使用crc32对特定大小的文件执行一个步骤。那个大小可能是1K左右。对于较长的文件,adler32crc32将具有接近相同的碰撞概率。

根据您拥有的文件数量,您可以考虑使用较大哈希值的后续步骤,例如md5 or sha1。有关32位检查值的预期冲突的概率和计数,请参阅this answer。粗略地说,如果你有数百万个文件,那么这一步可能值得做。

通过更长的哈希值,您将无法获益。来自md5的128位足以区分世界上每台计算机上的所有文件。