【问题标题】:Understanding cyclic polynomial hash collisions了解循环多项式哈希冲突
【发布时间】:2013-05-03 18:38:29
【问题描述】:

我有一个代码,它使用循环多项式滚动哈希 (Buzhash) 来计算 n-gram 源代码的哈希值。如果我使用小的散列值(7-8 位),那么会有一些冲突,即不同的 n-gram 映射到相同的散列值。如果我将散列值中的位增加到 31,则有 0 次冲突 - 所有 ngram 映射到不同的散列值。

我想知道为什么会这样?冲突是取决于文本中 n-gram 的数量还是 n-gram 可以具有的不同字符的数量,还是取决于 n-gram 的大小?

在散列 n-gram(使用滚动散列)时如何选择散列值的位数?

【问题讨论】:

  • 冒着背叛我完全无知的风险...不是较小的哈希值总是更容易发生冲突吗? (其他一切都是平等的(可以这么说),意思是,相同的算法。)

标签: hash n-gram hash-collision


【解决方案1】:

长度如何影响碰撞

这只是一个排列问题。

如果我使用小的哈希值(7-8 位),那么会有一些冲突

好吧,让我们来分析一下。对于 8 位,可以为任何给定输入生成2^8 可能的二进制序列。即可以生成 256 个可能的哈希值,这意味着理论上,每个生成的256 消息摘要值都会保证发生冲突。这称为生日问题。

如果我将哈希值中的位数增加到 31,那么就有 0 次冲突 - 所有 ngram 都映射到不同的哈希值。

好吧,让我们应用相同的逻辑。使用 31 位精度,我们有2^31 可能的组合。那是2147483648 可能的组合。我们可以将其概括为:

Let N denote the amount of bits we use.
Amount of different hash values we can generate (X) = 2^N

Assuming repetition of values is allowed (which it is in this case!)

这是一个指数增长,这就是为什么使用 8 位时,您会发现很多冲突,而使用 31 位时,您会发现很少的冲突。

这对碰撞有何影响?

好吧,如果值非常少,并且每个值映射到输入的机会均等,那么您可以:

Let A denote the number of different values already generated.
Chance of a collision is: A / X 

Where X is the possible number of outputs the hashing algorithm can generate.

X 等于256 时,您有1/256 发生碰撞的机会,这是第一次。然后,当生成不同的值时,您就有2/256 发生碰撞的机会。直到最终,您已经生成了 255 个不同的值,并且您有 255/256 发生碰撞的机会。下一次,显然它变成了256/256 机会,或1,这是一个概率确定性。显然它通常不会达到这一点。碰撞发生的次数可能比每个256 周期要多得多。事实上,生日悖论告诉我们,在生成2^N/2 消息摘要值之后,我们可以开始期待碰撞。因此,按照我们的示例,那是在我们创建 16 唯一哈希之后。然而,我们确实知道,它必须至少在每256 个周期发生一次。哪个不好!

这意味着,在数学层面上,冲突的可能性与可能的输出数量成反比,这就是为什么我们需要将消息摘要的大小增加到合理的长度。

关于散列算法的说明

碰撞是完全不可避免的。这是因为,有大量可能的输入(2^所有可能的字符代码)和有限数量的可能输出(如上所示)。

【讨论】:

  • 吹毛求疵:可能的输入数量可能非常大,但不是无限的。
  • 公平点,它受到我们可以输入的可能字符代码数量的限制。修改。
  • 您可能想提一下生日悖论:您只需要使用 N 位散列散列大约 2^(N/2) 个值,就可以预料到会发生冲突。
  • 我想我可以。考虑到问题的主题,似乎细节太多了,但为什么不呢。
【解决方案2】:

如果你有 8 位的哈希值,那么可能的值总数是 256 - 这意味着如果你对 257 个不同的 n-gram 进行哈希处理,肯定会至少发生一次冲突(......而且很可能你会得到更多的冲突,即使少于 257 个 n-gram) - 无论散列算法或被散列的数据如何,都会发生这种情况。

如果您使用 32 位,则可能的值总数约为 40 亿 - 因此发生冲突的可能性要小得多。

'如何选择位数':我想取决于哈希的使用。如果它用于将 n-gram 存储在某种散列数据结构(字典)中,那么它应该与数据结构的“桶”的可能数量相关 - 例如如果字典的桶数少于 256,则 8 位散列是可以的。

请参阅this 了解一些背景

【讨论】:

    猜你喜欢
    • 2015-11-24
    • 2018-11-05
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 2020-11-04
    相关资源
    最近更新 更多