常见哈希碰撞概率分析
算法竞赛里,哈希是常用算法,且往往会引入随机性(或者对于判题程序而言随机的行为)。
了解这些套路,并且讨论他们的碰撞概率,是非常有趣而且有帮助的一件事!
字符串 - 多项式哈希
字符集大小不限,对于任意字符串 \(S = (s_1, s_2, \dots s_n)\),我们为其构造一个多项式 \(H(x)\):
由于带着多项式计算很慢,我们发现可以取大质数 \(P\),以及一个随机固定值 \(b \in [1,p)\)。
最终将 \(H(b) \pmod P\) 的值作为这个字符串的哈希值。
单次碰撞概率
给定两个 不同的 字符串 \(S_1, S_2\),长度分别为 \(n,m\ (n \ge m)\),其哈希值分别为 \(H_1(b),H_2(b)\)。
我们认为发生碰撞,当且仅当 \(H_1(b) \equiv H_2(b)\),希望分析其概率:
- 不妨两式相减,得到新的多项式 \(T(x) = H_1(x) - H_2(x)\)。
- 这一多项式的度数不超过 \(n\)。
根据 Schwartz-Zippel 引理,对于一个非恒为零的多项式,其总度数为 \(d\),如果我们从 \([1,p)\) 中随机挑选一个数 \(b\),代入多项式后,其值为零的概率 \(\le d/P\)。
也就是说,如果 \(b\) 对于数据/判题程序而言随机选取(对我们可以硬编码),则 \(H_1(b) = H_2(b)\) 的碰撞概率不超过 \(n/P\)。
在“多模哈希”的情况下,如果我们选取了 \(c\) 组 \((P,b)\),它们的碰撞概率相乘,为 \(n^c / \prod P_i\),变得更小了。
总体碰撞概率
称单次比较的碰撞概率为 \(n/P\),在给定了 \(t\) 个串的情况下,相互之间需要进行 \(\binom{t}{2}\) 轮比较,希望都没有碰撞。
我们先直接使用布尔不等式 Union Bound 进行宽松估计(已经足够使用),碰撞的概率不超过:
这样就可以考察需要多少字符串,来使得你的代码无法通过 任何测试点:
值得提醒的是,如果有 \(50\) 个测试点,那么单个测试点只需要 \(\le 5\%\) 的概率就会让你输掉比赛,可见单模数的危险。
如果允许理想地认为字符串的碰撞之间相互独立,还可以分析出更好的结果,单次无碰撞的概率为 \(1 - n/P\),则最终没有碰撞的概率是:
由于我们往往使 \(n/P\) 足够小,此处利用 \((1 - x) \approx e^{-x}\) 进行毛估估:
于是出现碰撞的概率不超过下式,这是更加紧的一个界(虽然对算法比赛而言不实用):
可重集 - 线性同余哈希
支持插入、删除元素;支持快速查询两个可重集是否一样。我们有至少 \(3\) 种做法,均在模意义下进行:
- 乘法哈希:取大质数 \(P\),将元素的值映射到随机值 \([1,P)\),随后计算乘积。
- 加法哈希 1:将元素的值映射到随机值 \([1,2^{64})\),随后计算加和。
- 加法哈希 2:取大质数 \(P\),将元素的值映射到随机值 \([1,P)\),随后计算加和。
结论是:都不错,但加法哈希 1 又快又好。我们先说明加法哈希的单次碰撞概率(总体碰撞概率的分析方法可参照前文)。
由于值进行了随机映射,看似概率应当均能分析为 \(1/V\) 的值域倒数形式,但实际上输入数字的出现次数是可以被构造的。
加法哈希
设数值 \(x\) 被映射为 \(h(x)\),集合 \(A,B\) 不相等,其中 \(x\) 分别出现了 \(c_A,c_B\) 次,频数差 \(\Delta = |c_A - c_B|\),对于输入可任意构造。
碰撞条件为线性同余方程 \(H(A) \equiv H(B) \pmod{2^{64}}\),移项,再将无关项写为 \(C\),得到:
因此可知方程的解数取决于 \(\gcd(\Delta, 2^{64})\),比赛环节下一般最坏可以被构造到 \(\Delta \approx 2^{20}\)。
此处自然溢出的碰撞概率最坏为 \(1 / 2^{40}\)。而如果选择了一个大质数 \(P\),则可以将概率变为 \(1/P\)。
乘法哈希
我们假设 \(H(A) = h(x)^{c_A} \cdot V_A\),\(H(B) = h(x)^{c_B} \cdot V_B\),其中 \(V_A,V_B\) 是其他项的乘积。则碰撞条件:
不妨设 \(c_A > c_B\),且令 \(C =V_B \cdot V_A^{-1} \pmod P\),改写碰撞条件为:
随后由于存在原根 \(g\),改写 $h(x) \equiv g^u $ 与 \(C \equiv g^v\) 可得到:
明显这里指数位置是“相同”的,在 mod 群的阶的意义下,有线性同余方程:
也就是说,方程的解数取决于 \(d = \gcd(\Delta, P-1)\),然而此处 \(P-1\) 总归是一个偶数,故不及加法哈希来得好。

浙公网安备 33010602011771号