我的目标是有效地执行目录树的详尽差异。给定一组文件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
答案 0 :(得分:1)
我建议先使用adler32
, then crc32
。可能有许多非常短的文件具有相同的adler32
,但不同的crc32
。实际上,您可以考虑在第一遍中使用crc32
对特定大小的文件执行一个步骤。那个大小可能是1K左右。对于较长的文件,adler32
和crc32
将具有接近相同的碰撞概率。
根据您拥有的文件数量,您可以考虑使用较大哈希值的后续步骤,例如md5
or sha1
。有关32位检查值的预期冲突的概率和计数,请参阅this answer。粗略地说,如果你有数百万个文件,那么这一步可能值得做。
通过更长的哈希值,您将无法获益。来自md5的128位足以区分世界上每台计算机上的所有文件。