[100分]寻找哈希值一样的字符串

CsToD 2010-07-09 11:27:34
string类型的实例是无限的,而哈希值是一个32位整数,所以肯定存在哈希值相同的字符串。

string类型的哈希算法如下:

public override unsafe int GetHashCode()
{
fixed (char* str = ((char*) this))
{
char* chPtr = str;
int num = 0x15051505;
int num2 = num;
int* numPtr = (int*) chPtr;
for (int i = this.Length; i > 0; i -= 4)
{
num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
if (i <= 2)
{
break;
}
num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
numPtr += 2;
}
return (num + (num2 * 0x5d588b65));
}
}


谁能找出几个哈希值相同的字符串?
...全文
1173 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
mrsupersky 2012-02-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 amandag 的回复:]

概率极低
[/Quote]


public static unsafe int GetHashCode(string strsrc)
{
fixed (char* str = strsrc)
{
char* chPtr = str;
int num = 0x15051505;
int num2 = num;
int* numPtr = (int*)chPtr;
for (int i = strsrc.Length; i > 0; i -= 4)
{
num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
if (i <= 2)
{
break;
}
num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
numPtr += 2;
}
return (num + (num2 * 0x5d588b65));
}
}



Dictionary<uint, string> src = new Dictionary<uint, string>();

List<uint> other = new List<uint>(2000000);

int result = 0;
timer.Reset();

timer.Start();

for (int i = 0; i < 2000000; i++)
{
uint ii = (uint)myHash.GetHashCode(i.ToString());
if (!src.ContainsKey(ii))
{
src.Add(ii, i.ToString());
}
else
{
textBox1.AppendText(ii.ToString() + "—");
}
}

//result = myHash.GetHash(textBox1.Text);
timer.Stop();
MessageBox.Show(result + "Time:" + timer.ElapsedTicks + "\r\n List<int> num is:" + other.Count.ToString());


200万就出现Hash重复的了
苍鹫 2011-09-19
  • 打赏
  • 举报
回复
恩,哈希值还不是很理解,学习啦
「已注销」 2010-07-14
  • 打赏
  • 举报
回复
每天回帖即可获得10分可用分
air123456789 2010-07-14
  • 打赏
  • 举报
回复
不知道是什么意思,来学习,一天十分。
angel6709 2010-07-14
  • 打赏
  • 举报
回复
问题解决了,楼主结贴吧
angel6709 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 0009 的回复:]
引用 23 楼 angel6709 的回复:

引用 22 楼 0009 的回复:
你只要构造一个有 4294967296 个不重复字符串的集合,就至少能找到一对碰撞,这样的集合并不难构造。

呵呵,我上面构造的集合碰撞了89211次


Great!

这么密集的碰撞真让我有点惊讶。看来有些情况下不能随便信任GetHashCode了,包括随便使用Dictionary<>。
[/Quote]
同意。。。
RexZheng 2010-07-12
  • 打赏
  • 举报
回复

有些情况下不能随便信任GetHashCode了
==>
有些情况下不能随便信任String的GetHashCode()值了
RexZheng 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 angel6709 的回复:]

引用 22 楼 0009 的回复:
你只要构造一个有 4294967296 个不重复字符串的集合,就至少能找到一对碰撞,这样的集合并不难构造。

呵呵,我上面构造的集合碰撞了89211次
[/Quote]

Great!

这么密集的碰撞真让我有点惊讶。看来有些情况下不能随便信任GetHashCode了,包括随便使用Dictionary<>。
angel6709 2010-07-12
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 0009 的回复:]
你只要构造一个有 4294967296 个不重复字符串的集合,就至少能找到一对碰撞,这样的集合并不难构造。
[/Quote]
呵呵,我上面构造的集合碰撞了89211
RexZheng 2010-07-12
  • 打赏
  • 举报
回复
你只要构造一个有 4294967296 个不重复字符串的集合,就至少能找到一对碰撞,这样的集合并不难构造。
angel6709 2010-07-12
  • 打赏
  • 举报
回复
r.Add("a");//你这啥玩艺?
是省略的写法,正确写法是,当然也没有判断s的长度为0的情况和溢出处理。。。。
r.add(s[0].tostring())

public static List<string> P(string s)
假设传入"abc"
则返回list包含:
""
"a"
"b"
"ab"
"ba"
"c"
"ac"
"ca"
"bc"
"cb"
"abc"
"acb"
"cba"
"bac"
"bca"
"cba"
angel6709 2010-07-12
  • 打赏
  • 举报
回复
你运行一下就知道了,
求一个集合的所有子集,
然后再求这些子集的全排列。
CsToD 2010-07-10
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 angel6709 的回复:]
C# code


public static List<string> P(string s)
{
if (s.Length==1)
{
List<string> r = new List<string>();
r.Add("");
……
[/Quote]

你这啥玩艺?


public static List<string> P(string s)
{
if (s.Length==1)
{
List<string> r = new List<string>();
r.Add("");//你这啥玩艺?
r.Add("a");//你这啥玩艺?
return r;
}
else...
}
-小蕾- 2010-07-09
  • 打赏
  • 举报
回复
学习了。。。
小夏天~ 2010-07-09
  • 打赏
  • 举报
回复
不了解,帮顶..
angel6709 2010-07-09
  • 打赏
  • 举报
回复
楼上,好久不见呵呵
liherun 2010-07-09
  • 打赏
  • 举报
回复
楼主总是研究深奥的问题
angel6709 2010-07-09
  • 打赏
  • 举报
回复
很多很多。。。
angel6709 2010-07-09
  • 打赏
  • 举报
回复
MessageBox.Show("fbdace".GetHashCode().ToString() + ":" + "fedac".GetHashCode().ToString());
angel6709 2010-07-09
  • 打赏
  • 举报
回复
 

public static List<string> P(string s)
{
if (s.Length==1)
{
List<string> r = new List<string>();
r.Add("");
r.Add("a");
return r;
}
else
{
List<string> tmp = P(s.Substring(0, s.Length - 1));
List<string> ret=new List<string>();
foreach (string t in tmp)
{
ret.Add(t);
}

foreach (string t in tmp)
{
for (int len = t.Length; len >=0; len--)
{
string insert = t;
insert=insert.Insert(len, s[s.Length - 1].ToString());
ret.Add(insert);
}
}
return ret;
}
}





List<string> ret = P("abcdefghij");
Dictionary<int, string> dic = new Dictionary<int, string>();
foreach (string s in ret)
{
try
{
dic.Add(s.GetHashCode(), s);
}
catch
{
MessageBox.Show(s + "_" + dic[s.GetHashCode()]);
}
}
加载更多回复(11)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧