1. 反哈希攻击(故意构造碰撞)在竞赛中的防御策略
在算法竞赛中,当使用哈希函数时,如果出题人或攻击者故意构造碰撞(使不同输入映射到相同哈希值),应当采取哪些防御策略?
- 哈希碰撞攻击的原理与危害
- 随机化选择基数/模数防御
- 双哈希与自然溢出的防御结合
反哈希攻击的核心是让攻击者无法预测哈希参数。常用防御策略包括:使用大素数模数(如 10^9+7、10^9+9)并随机选择基数(base),使攻击者无法预先构造针对固定基数的碰撞对;采用双哈希(两个不同模数/基数组合)或三重哈希,将碰撞概率降到可忽略;对字符串哈希使用随机化基数,使每次运行都不同,从而让针对单一固定基数的卡哈希攻击失效。此外,可用自然溢出(unsigned long long 模 2^64)配合随机基数,但需注意模运算溢出后可能被精密构造,故更稳妥的是大素数模+随机基数。
攻击若能预制碰撞,哈希的 O(1) 期望就退化为 O(n) 最坏。随机化基数让攻击者无法离线构造碰撞集合,因为每次运行参数不同;双哈希让两个独立哈希同时碰撞的概率降到乘积量级,从而概率性保证正确。
import java.util.Random;
// 随机化基数的字符串哈希,防御卡哈希
class RandomHash {
static final long MOD = 1_000_000_007L;
static final Random rnd = new Random();
static final long BASE = 100 + rnd.nextInt(100000); // 随机基数
public static long hash(String s) {
long h = 0;
for (char c : s.toCharArray()) h = (h * BASE + c) % MOD;
return h;
}
}