长度如何影响碰撞
这只是一个排列的问题。
如果我使用小的哈希值(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
equals时256
,您有1/256
可能第一次发生碰撞。然后2/256
,当生成不同的值时,您就有可能发生碰撞。直到最终,您已经生成了 255 个不同的值,并且您有255/256
可能发生碰撞。下一次,显然它变成了一个256/256
机会,或者1
,这是一个概率确定性。显然它通常不会达到这一点。碰撞发生的次数可能比每个256
周期都要多得多。事实上,生日悖论告诉我们,2^N/2
在生成消息摘要值之后,我们可以开始期待冲突。因此,按照我们的示例,那是在我们创建16
唯一哈希之后。然而,我们确实知道,它至少必须发生, 每个256
周期。哪个不好!
这意味着,在数学层面上,冲突的可能性与可能的输出数量成反比,这就是为什么我们需要将消息摘要的大小增加到合理长度的原因。
关于散列算法的说明
碰撞是完全无法避免的。这是因为,有大量可能的输入(2^所有可能的字符代码)和有限数量的可能输出(如上所示)。