生成两个具有相同哈希码的不同字符串
Generate two different strings with the same hashcode
我想做一些测试,需要一些字符串具有相同的散列码,但不是相同的字符串。我找不到任何例子,所以我决定写一个简单的程序来帮我做。
下面的代码反复生成两个随机字符串,直到它们生成相同的哈希码。
static Random r = new Random();
static void Main(string[] args)
{
string str1, str2;
do
{
str1 = GenerateString();
str2 = GenerateString();
} while (str1.GetHashCode() != str2.GetHashCode() && str1 != str2);
Console.WriteLine("{0}\n{1}", str1, str2);
}
static string GenerateString()
{
string s = "";
while (s.Length < 6)
{
s += (char)r.Next(char.MaxValue);
}
return s;
}
此代码似乎(理论上)有效,但可能需要几个世纪才能完成。所以我想反之亦然,从一个哈希码生成两个字符串。
我知道不可能从哈希码中检索字符串,但是否可以从中生成可能的字符串?
我使用的是 Visual Studio 2015 社区版。版本:14.0.23107.0D14REL.
.NET 框架:4.6.00081.
利用Birthday Paradox。不要只直接测试两个字符串,而是测试你以前见过的所有字符串。
using System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var words = new Dictionary<int, string>();
int i = 0;
string teststring;
while (true)
{
i++;
teststring = i.ToString();
try
{
words.Add(teststring.GetHashCode(), teststring);
}
catch (Exception)
{
break;
}
}
var collisionHash = teststring.GetHashCode();
Console.WriteLine("\"{0}\" and \"{1}\" have the same hash code {2}", words[collisionHash], teststring, collisionHash);
Console.ReadLine();
}
}
}
对于我的机器,它产生输出
"699391" and "1241308" have the same hash code -1612916492
几乎是瞬间。
由于 .NET 中字符串的哈希处理方式,您可能无法获得与我完全相同的输出,但它应该一样快。
通过反复比较随机字符串来查找两个字符串几乎要花很长时间。而是生成字符串并通过哈希码将它们存储在字典中。然后逐一查找。很快就找到了匹配项。
MATCH FOUND!! xqzrbn and krumld hash code 80425224
void Main()
{
var lookup = new Dictionary<int,string>();
while(true) {
var s = RandomString();
var h = s.GetHashCode();
string s2;
if (lookup.TryGetValue(h, out s2) && s2 != s) {
Console.WriteLine("MATCH FOUND!! {0} and {1} hash code {2}",
lookup[h],
s,
h);
break;
}
lookup[h] = s;
if (lookup.Count % 1000 == 0) {
Console.WriteLine(lookup.Count);
}
}
}
static Random r = new Random();
// Define other methods and classes here
static string RandomString() {
var s = ((char)r.Next((int)'a',((int)'z')+1)).ToString() +
((char)r.Next((int)'a',((int)'z')+1)).ToString() +
((char)r.Next((int)'a',((int)'z')+1)).ToString() +
((char)r.Next((int)'a',((int)'z')+1)).ToString() +
((char)r.Next((int)'a',((int)'z')+1)).ToString() +
((char)r.Next((int)'a',((int)'z')+1)).ToString();
return s;
}
我想做一些测试,需要一些字符串具有相同的散列码,但不是相同的字符串。我找不到任何例子,所以我决定写一个简单的程序来帮我做。
下面的代码反复生成两个随机字符串,直到它们生成相同的哈希码。
static Random r = new Random();
static void Main(string[] args)
{
string str1, str2;
do
{
str1 = GenerateString();
str2 = GenerateString();
} while (str1.GetHashCode() != str2.GetHashCode() && str1 != str2);
Console.WriteLine("{0}\n{1}", str1, str2);
}
static string GenerateString()
{
string s = "";
while (s.Length < 6)
{
s += (char)r.Next(char.MaxValue);
}
return s;
}
此代码似乎(理论上)有效,但可能需要几个世纪才能完成。所以我想反之亦然,从一个哈希码生成两个字符串。
我知道不可能从哈希码中检索字符串,但是否可以从中生成可能的字符串?
我使用的是 Visual Studio 2015 社区版。版本:14.0.23107.0D14REL.
.NET 框架:4.6.00081.
利用Birthday Paradox。不要只直接测试两个字符串,而是测试你以前见过的所有字符串。
using System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var words = new Dictionary<int, string>();
int i = 0;
string teststring;
while (true)
{
i++;
teststring = i.ToString();
try
{
words.Add(teststring.GetHashCode(), teststring);
}
catch (Exception)
{
break;
}
}
var collisionHash = teststring.GetHashCode();
Console.WriteLine("\"{0}\" and \"{1}\" have the same hash code {2}", words[collisionHash], teststring, collisionHash);
Console.ReadLine();
}
}
}
对于我的机器,它产生输出
"699391" and "1241308" have the same hash code -1612916492
几乎是瞬间。
由于 .NET 中字符串的哈希处理方式,您可能无法获得与我完全相同的输出,但它应该一样快。
通过反复比较随机字符串来查找两个字符串几乎要花很长时间。而是生成字符串并通过哈希码将它们存储在字典中。然后逐一查找。很快就找到了匹配项。
MATCH FOUND!! xqzrbn and krumld hash code 80425224
void Main()
{
var lookup = new Dictionary<int,string>();
while(true) {
var s = RandomString();
var h = s.GetHashCode();
string s2;
if (lookup.TryGetValue(h, out s2) && s2 != s) {
Console.WriteLine("MATCH FOUND!! {0} and {1} hash code {2}",
lookup[h],
s,
h);
break;
}
lookup[h] = s;
if (lookup.Count % 1000 == 0) {
Console.WriteLine(lookup.Count);
}
}
}
static Random r = new Random();
// Define other methods and classes here
static string RandomString() {
var s = ((char)r.Next((int)'a',((int)'z')+1)).ToString() +
((char)r.Next((int)'a',((int)'z')+1)).ToString() +
((char)r.Next((int)'a',((int)'z')+1)).ToString() +
((char)r.Next((int)'a',((int)'z')+1)).ToString() +
((char)r.Next((int)'a',((int)'z')+1)).ToString() +
((char)r.Next((int)'a',((int)'z')+1)).ToString();
return s;
}