30

我正在为搜索系统开发一个后端应用程序。搜索系统将文件复制到一个临时目录并给它们随机命名。然后它将临时文件的名称传递给我的应用程序。我的应用程序必须在有限的时间内处理每个文件,否则它会被关闭——这是一种类似看门狗的安全措施。处理文件可能需要很长时间,因此我需要设计能够处理这种情况的应用程序。如果我的应用程序在下次搜索系统想要索引同一个文件时关闭,它可能会给它一个不同的临时名称。

显而易见的解决方案是在搜索系统和后端之间提供一个中间层。它将请求排队到后端并等待结果到达。如果请求在中间层超时 - 没问题,后端将继续工作,只有中间层重新启动,当搜索系统稍后重复请求时,它可以从后端检索结果。

问题是如何识别文件。他们的名字随机变化。我打算使用像 MD5 这样的散列函数来散列文件内容。我很清楚生日悖论,并使用链接文章中的估计来计算概率。如果我假设我的文件不超过 100 000 个,则两个文件具有相同 MD5(128 位)的概率约为 1,47x10 -29

我应该关心这种冲突概率还是只是假设相等的哈希值意味着相等的文件内容?

4

5 回答 5

43

相等的哈希意味着相等的文件,除非有人恶意破坏您的文件并注入冲突。(如果他们从互联网上下载东西,可能就是这种情况)如果是这种情况,请使用基于 SHA2 的功能。

没有意外的 MD5 碰撞,1,47x10 -29是一个非常非常非常小的数字。

为了克服重新散列大文件的问题,我将采用 3 阶段身份方案。

  1. 单独的文件大小
  2. 文件大小 + 文件中不同位置的 64K * 4 哈希
  3. 一个完整的哈希

因此,如果您看到一个具有新大小的文件,您肯定知道您没有重复文件。等等。

于 2009-05-14T10:15:43.490 回答
4

仅仅因为概率是 1/X 并不意味着在您拥有 X 条记录之前它不会发生在您身上。就像彩票一样,你不太可能赢,有人会赢

随着当今计算机的速度和容量(甚至不谈论安全性,只谈论可靠性),真的没有理由不使用比 MD5 更大/更好的散列函数来处理任何关键问题。升级到 SHA-1 应该可以帮助您在晚上睡得更好,但如果您想格外小心,请转到 SHA-265,永远不要再考虑它。

如果性能确实是一个问题,那么使用实际上比 MD5 更快但支持 256+ 位的 BLAKE2 以降低冲突的可能性,同时具有相同或更好的性能。然而,虽然 BLAKE2 已被广泛采用,但它可能需要向您的项目添加新的依赖项。

于 2016-09-30T19:38:05.957 回答
3

我认为你不应该。

但是,如果您有两个相同文件具有不同(真实名称,不是基于 md5)的概念,您应该这样做。例如,在搜索系统中,两个文档可能具有完全相同的内容,但由于它们位于不同的位置而不同。

于 2009-05-14T09:14:12.297 回答
2

我想出了一种蒙特卡洛方法,以便在将 UUID 用于必须序列化而不会发生冲突的分布式系统时能够安全地睡觉。

from random import randint
from math import log
from collections import Counter

def colltest(exp):
    uniques = []
    while True:
        r = randint(0,2**exp)
        if r in uniques:
            return log(len(uniques) + 1, 2)
        uniques.append(r)

for k,v in Counter([colltest(20) for i in xrange(1000)]):
    print k, "hash orders of magnitude events before collission:",v

会打印出类似的东西:

5 hash orders of magnitude events before collission: 1
6 hash orders of magnitude events before collission: 5
7 hash orders of magnitude events before collission: 21
8 hash orders of magnitude events before collission: 91
9 hash orders of magnitude events before collission: 274
10 hash orders of magnitude events before collission: 469
11 hash orders of magnitude events before collission: 138
12 hash orders of magnitude events before collission: 1

我之前听过这个公式:如果你需要存储 log(x/2) 键,请使用至少具有键空间 e**(x) 的散列函数。

重复的实验表明,对于 1000 个 log-20 空间的群体,有时早在 log(x/4) 时就会发生碰撞。

对于 122 位的 uuid4,这意味着我可以安全地睡觉,而几台计算机会随机选择 uuid,直到我有大约 2**31 个项目。我正在考虑的系统中的峰值事务大约是每秒 10-20 个事件,我假设平均为 7 个。考虑到极端的偏执,这给了我大约 10 年的操作窗口。

于 2015-01-30T14:17:34.560 回答
1

这是一个交互式计算器,可让您估计任何散列大小和对象数量的冲突概率 - http://everydayinternetstuff.com/2015/04/hash-collision-probability-calculator/

于 2015-04-23T13:51:05.183 回答