如何评估哈希冲突概率?

问题描述 投票:0回答:6

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

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

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

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

language-agnostic md5 probability estimation
6个回答
44
投票

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

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

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

  1. 仅文件大小
  2. Filesize + 文件中不同位置的 64K * 4 的 hash
  3. 完整的哈希

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


4
投票

仅仅因为概率是 1/X 并不意味着它不会发生在你身上直到你有 X 条记录。这就像彩票一样,你不太可能中奖,但是 someone will win.

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

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


3
投票

我认为你不应该。

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


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 年的操作窗口。


1
投票

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


0
投票

对于临时文件名,使用操作系统功能。它可能使用中间子目录、Unix-epoch 等

© www.soinside.com 2019 - 2024. All rights reserved.