哈希碰撞概率计算

哈希碰撞概率计算

数学推导

假如取值空间为 $d$,取值范围为 $n$,可得均不碰撞的概率为:

$$\overline{p}(n) = 1 \cdot \Big(1 – \frac{1}{d}\Big) \cdot \Big(1 – \frac{2}{d}\Big) \cdots \Big(1 – \frac{n-1}{d}\Big)$$

推导可得,存在碰撞的概率为:

$$p(n) = 1 – \overline{p}(n)$$

根据泰勒公式,指数函数 $e^x$ 可以展开成多项式

$$e^x = \sum_{k=1}^\infty \frac{x^k}{k!} = 1 + x + \frac{x^2}{2} + \frac{x^3}{6} + \cdots$$

当 $ x \to 0$ 时,

$$e^x \approx 1 + x $$

代入$-\dfrac{1}{d}$可得:

$$e^{-\frac{1}{d}} \approx 1 -\frac{1}{d}$$

代入$p(n)$ 可得:

$$p(n,d) \approx 1 – e^{ – \frac{n(n – 1)}{2d}}$$

代码实现

const calculate = (d, n) => {
  const exponent = (-n * (n - 1)) / (2 * d)
  return 1 - Math.E ** exponent;
}

模拟场景

如果使用时间戳作为输入生成哈希值,发生哈希碰撞的概率是多少?

// qps = 1
calculate(1000, 1);  // 0
// qps = 38
calculate(1000, 38); // 0.5049022197190565
// qps = 50
calculate(1000, 50); // 0.7062422996764672

参考文献

[1] http://ruanyifeng.com/blog/2018/09/hash-collision-and-birthday-attack.html