长度如何影响碰撞
这只是一个排列问题。
如果我使用小的哈希值(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^所有可能的字符代码)和有限数量的可能输出(如上所示)。