【问题标题】:Generating variations of checksum functions to minimize collisions生成校验和函数的变化以最小化冲突
【发布时间】:2013-10-05 09:31:12
【问题描述】:

我的目标是有效地执行目录树的详尽差异。给定一组文件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ₙ]] 开始,然后根据一些 @987654329 反复将其拆分为更精细的类 EQV₁EQV₂...EQVₘ₋₁ @启发式,例如,文件大小,校验和函数1,校验和2。在应用了所有m启发式(EQVₘ₋₁)之后,必须对EQVₘ₋₁中每个类中的所有文件进行成对差异。因为这最后一步对于EQVₘ₋₁ 中的每个类都是二次的,即

O(sum(n² for n in map(len, EQVₘ₋₁)) )

如果每个 m 拆分都在线性时间内完成,那么可能会成为我算法的瓶颈,我的目标是使 EQVₘ₋₁ 尽可能平坦。

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

考虑到我可以在一次读取文件中计算给定文件的所有哈希值,我如何计算各种哈希值来帮助我区分不同的文件?

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

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

【问题讨论】:

  • 感谢@Veedrac 的编辑,现在我知道如何格式化这些数学符号了。

标签: python diff md5 hash-function adler32


【解决方案1】:

我建议首先使用adler32, then crc32。可能有许多非常短的文件具有相同的adler32,但不同的crc32。事实上,您可以考虑在第一遍对低于特定大小的文件使用crc32 的单个步骤。该大小可能约为1K。对于较长的文件,adler32crc32 将具有接近相同的冲突概率。

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

使用更长的哈希值不会给您带来任何好处。来自 md5 的 128 位足以区分世界上每台计算机上的所有文件。

【讨论】:

  • 感谢有关小文件的提示,我确实注意到一些最大的类通常是那些带有小文件的类。由于我可以在同一个文件上计算恒定数量的 adler32s 的不同起始字节而不会产生额外的复杂性,因此我正在考虑在前 10 个 128 字节的块上计算 adler32。如果文件确实不同,这 10 个adler32s 是否可能不同?
  • 另外,感谢您回答我的问题!从这个有用算法的同一作者那里得到答案真是令人惊喜。
  • 128 字节的输入对于adler32 来说太少了。你应该至少做 1K 块。然后您将充分利用 32 位。
  • 我的意思是,10 adler32s 从前 128 个块中的每一个开始,即好像文件在此之前已被截断。不是 adler32 仅在一个 128 字节的块上,如果不清楚,抱歉。
  • 更简单、更快的方法是简单地执行两个adler32s,每个在文件的一半上。这有效地为您提供了 64 位检查而不是 32 位检查,不同文件的冲突概率要低得多。在此应用程序中执行两个以上独立的adler32s 将大大减少回报。和以前一样,您应该在小于 1K 的文件上使用 crc32,如果将文件一分为二,则应在小于 2K 的文件上使用 crc32
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2016-09-07
  • 1970-01-01
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多