如何用C#默认哈希函数生成三个哈希值相同的不同字符串
解决C#字符串三哈希碰撞问题
首先纠正你现有代码的逻辑错误:你的代码输出结果中A的哈希值和B、C不一致,是因为当捕获第二次碰撞时,当前hash变量是第二个碰撞字符串的哈希,而myList[0]是第一次碰撞的字符串(它的哈希和当前hash完全不同),等于误把不同哈希的字符串当成了同组碰撞。
下面提供两种可行的解决方法:
方案一:直接使用已知碰撞字符串
根据.NET版本的不同,有现成的已验证碰撞字符串:
.NET Framework环境
以下三个不同字符串的GetHashCode()结果完全相同:
string A = "FB"; string B = "Ea"; string C = "D`";
验证代码:
Console.WriteLine(A.GetHashCode()); // 三者输出相同值 Console.WriteLine(B.GetHashCode()); Console.WriteLine(C.GetHashCode());
.NET Core/.NET 5+环境
可以用这三个字符串:
string A = "aMz"; string B = "aNA"; string C = "aO,";
方案二:改进搜索程序批量查找
如果需要自己搜索碰撞字符串,修改代码记录每个哈希对应的所有字符串,直到找到某个哈希对应至少三个不同字符串:
var hashGroups = new Dictionary<int, List<string>>(); int stringCounter = 0; while (true) { stringCounter++; string currentStr = stringCounter.ToString(); int hash = currentStr.GetHashCode(); if (!hashGroups.ContainsKey(hash)) { hashGroups[hash] = new List<string>(); } hashGroups[hash].Add(currentStr); // 找到包含3个字符串的哈希组就终止 if (hashGroups[hash].Count >= 3) { var group = hashGroups[hash]; string A = group[0]; string B = group[1]; string C = group[2]; Console.WriteLine($"找到三个碰撞字符串:"); Console.WriteLine($"A: {A},哈希值:{A.GetHashCode()}"); Console.WriteLine($"B: {B},哈希值:{B.GetHashCode()}"); Console.WriteLine($"C: {C},哈希值:{C.GetHashCode()}"); break; } }
代码说明
- 用
Dictionary<int, List<string>>存储每个哈希对应的所有字符串,避免丢失之前的碰撞记录 - 每次生成新字符串后加入对应哈希的列表,一旦某个列表长度达到3,直接输出结果
- 若觉得数字字符串碰撞概率低,可改成随机生成包含字母、符号的字符串,能更快找到碰撞
补充提示
- 哈希碰撞是必然的(鸽巢原理:int只有2^32种可能,字符串数量无限)
- .NET不同版本的字符串哈希算法有差异,碰撞字符串不通用,需匹配运行环境
内容的提问来源于stack exchange,提问作者Ahmadou Kassoum
相关产品推荐
相关产品推荐

