可能重复:
What is the best algorithm for an overridden System.Object.GetHashCode?
我需要为包含三个字符串的类型重写GetHashCode方法。这是我的代码:
protected override int GetHashCode()
{
return str1.GetHashCode() + str2.GetHashCode() + str3.GetHashCode();
}
这种方法实现的安全方法是什么?
答案 0 :(得分:18)
最好的方法是避免在下列情况下产生相同哈希码的任何内容:
这些帐户的添加(单独)和XOR都失败。
这是一个更好的方法:
public override int GetHashCode()
{
unchecked
{
int result = 37; // prime
result *= 397; // also prime (see note)
if (str1 != null)
result += str1.GetHashCode();
result *= 397;
if (str2 != null)
result += str2.GetHashCode();
result *= 397;
if (str2 != null)
result += str2.GetHashCode();
return result;
}
}
无论你在代码中使用加法还是异或都有争议,我已经看到使用两者的例子,没有明确分析哪些是优越的(即均匀分布)。选择一个并继续使用它。
397是ReSharper addin when it generates GetHashCode implementations使用的默认值,显然是选中的,因为它通常会溢出int的范围,从而更好地混合位。围绕这种特定格式的GetHashCode实现有很多理论,但它是最常用的。
答案 1 :(得分:4)
我总是使用exclusive或(Xor)而不是添加,因为它不具有在任何地方获取数字的倾向(比如朝向大值)。所以我会说那个
protected override int GetHashCode()
{ return str1.GetHashCode() ^ str2.GetHashCode() ^ str3.GetHashCode(); }
是一种更好的实施方式。
您也可以尝试使用其中的变体,例如
protected override int GetHashCode()
{
unchecked
{
return (str1.GetHashCode() * 1369) ^
(str2.GetHashCode() * 37) ^ str3.GetHashCode();
}
}
如果要确保切换字符串的值会产生不同的结果。有各种各样的方法可用于散列(例如universal hashing),所以只需搜索散列方法,如果这就是你要找的东西。