Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这个散列函数会经常发生冲突吗?_C#_Hash_Hash Collision_Hash Code Uniqueness - Fatal编程技术网

C# 这个散列函数会经常发生冲突吗?

C# 这个散列函数会经常发生冲突吗?,c#,hash,hash-collision,hash-code-uniqueness,C#,Hash,Hash Collision,Hash Code Uniqueness,我使用以下代码生成对象的哈希: public int GetHashCode(MyType obj) { return (obj.Prop1.GetHashCode() + obj.Prop2.GetHashCode() + obj.Prop3.GetHashCode()).GetHashCode(); } 也就是说,我添加所有属性的散列码,然后获取该属性的散列 在评论中,一位同事建议,这将导致碰撞过于频繁。我不确定这是真的,因为: 考虑到散列码在正数和负数之间以相同的频率选择,并且它们

我使用以下代码生成对象的哈希:

public int GetHashCode(MyType obj)
{
   return (obj.Prop1.GetHashCode() + obj.Prop2.GetHashCode() + obj.Prop3.GetHashCode()).GetHashCode();
}
也就是说,我添加所有属性的散列码,然后获取该属性的散列

在评论中,一位同事建议,这将导致碰撞过于频繁。我不确定这是真的,因为:

  • 考虑到散列码在正数和负数之间以相同的频率选择,并且它们环绕在一起,我认为我们没有获得任何关于这些数和的可能性的额外信息,而不是这些数本身
  • 由于它们的总和是非随机的,散列码的设计目的是使“靠得很近”的数字变得“相距很远”,因此将非均匀分布的值输入函数不应该是一个问题
  • 谁是对的

    如果答案是特定于语言的,则用C#表示。

    最好是:

    public int GetHashCode(MyType obj)
    {
       return obj.Prop1.GetHashCode() ^ 
              obj.Prop2.GetHashCode() ^ 
              obj.Prop3.GetHashCode();
    }
    

    假设Prop1、Prop2等的类型为
    int
    。通常只使用较低范围的整数。你的求和方法会经常发生冲突

    7
    的HasCode是7,当它自己对
    int
    进行散列时,这非常有意义。但是在代码中,元组
    都具有相同的哈希值。简单的异或而不是加法也是如此

    常用的方法是添加一些(素数)并移位:

    public int GetHashCode(MyType obj)
    {
      int hash = 0;
      unchecked
      {         
         hash += 19 * obj.Prop1.GetHashCode();
         hash += 31 * obj.Prop2.GetHashCode();
         hash += 37 * obj.Prop3.GetHashCode();
      }
      return hash;
    }
    

    数字19、31、37并不太关键。如果您喜欢使用OR或XOR而不是
    +

    您可以使用经过修改的FNV哈希代码生成器,我已经回答了一个非常类似的问题

    你同事的理由是什么?参见亨克·霍特曼的推理。如果某些属性的GetHashCode不使用整个范围,则与移位混合应提供更好的分布…素数很好,并且比移位更可取,因为简单的分块算法可能只取哈希代码的较低N位;如果属性发生移动,它们最终可能会被完全忽略。