string.GetHashCode()唯一性和冲突

时间:2012-07-23 06:04:13

标签: c# .net

鉴于两个不同的字符串,s.GetHashCode() != s1.GetHashCode()

的情况总是如此

不同整数的数量是否小于不同字符串的数量?

3 个答案:

答案 0 :(得分:12)

没有。就像一个简单的思想实验:有多少个字符串(提示:多于2个 32 ,因此可以有多少个唯一的哈希码(提示:2 32 See the problem?

Equals返回两个对象相等时,只需要相等的哈希码。此外,只要两个哈希码相等,那么对象本身就不能相等。没有进一步的要求,但它们应该分布良好,以便哈希表可以很好地运行。所以基本上是:

enter image description here

请注意省略相应的⇐变体。它不是等价的,仅仅是两个含义。

引用documentation

  

哈希函数必须具有以下属性:

     
      
  1. 如果两个对象比较相等,则每个对象的GetHashCode方法必须返回相同的值。但是,如果两个对象的比较不相等,则两个对象的GetHashCode方法不必返回不同的值。

  2.   
  3. 对象的GetHashCode方法必须始终返回相同的哈希码,只要对对象状态没有修改即可确定对象的Equals方法的返回值。请注意,这仅适用于当前应用程序的执行,并且如果再次运行应用程序,则可以返回不同的哈希代码。

  4.   
  5. 为获得最佳性能,哈希函数必须为所有输入生成随机分布。

  6.   

答案 1 :(得分:6)

要添加到@ Joey的语句,主要不能使哈希码始终不相等。

有2 ^ 32个可能的哈希码但是无限输入字符串。

哈希冲突保证以足够的(2 ^ 32 + 1)输入值发生。

事实上,由于Birthday Problem,哈希冲突比人们想象的要普遍得多。当我对一个使用64位哈希码的系统进行数学计算时(其中方式比32位哈希码更可能的哈希值,而不是像人们想象的那样加倍), 1亿个输入值很可能会发生至少1次哈希冲突。我认为概率大约是1%。

答案 2 :(得分:0)

据我所知,Object.GetHashCode()没有提供对象的哈希函数(因此我认为Joey在这种情况下的考虑不正确),它只返回CLR在对象时分配给对象的唯一索引在对象被垃圾收集时创建和释放。

因此,您不能在给定时刻重复使用哈希码(在同一个AppDomain中),但您可能会在一段时间内重复使用(在应用程序执行期间可能会多次分配相同的索引)。

这里还讨论了这个问题: Default implementation for Object.GetHashCode()