为啥在计算哈希码时使用 xor 运算符? [复制]
Posted
技术标签:
【中文标题】为啥在计算哈希码时使用 xor 运算符? [复制]【英文标题】:Why is the xor operator used in computing hash code? [duplicate]为什么在计算哈希码时使用 xor 运算符? [复制] 【发布时间】:2013-10-08 23:22:12 【问题描述】:在这篇 MSDN 文章中 http://msdn.microsoft.com/en-us/library/ms132123.aspx 它讨论了 Class Equalitycomparer 并有一个例子。在这个关于比较盒子的例子中,它有这个类 -
class BoxSameDimensions : EqualityComparer<Box>
public override bool Equals(Box b1, Box b2)
if (b1.Height == b2.Height & b1.Length == b2.Length
& b1.Width == b2.Width)
return true;
else
return false;
public override int GetHashCode(Box bx)
int hCode = bx.Height ^ bx.Length ^ bx.Width;
return hCode.GetHashCode();
我不明白这行 int hCode = bx.Height ^ bx.Length ^ bx.Width;
有人可以解释一下吗?为什么是异或?
【问题讨论】:
见***.com/q/371328/11683和***.com/q/263400/11683。 另见***.com/a/2334251/945456和csharpindepth.com/ViewNote.aspx?NoteID=27(后者解释了为什么异或实际上可能是一个坏主意) 【参考方案1】:^
运算符是bitwise exclusive-or operator。
在这种情况下,它被用作从三个整数生成哈希码的便捷方式。 (我不认为这是一个很好的方法,但这是一个不同的问题......)
奇怪的是,在构造了一个哈希码之后,他们又在上面使用了GetHashCode()
,这对于一个 int 来说完全没有意义,因为它只会返回 int 本身——所以它是一个空操作。
他们应该是这样写的:
public override int GetHashCode(Box bx)
return bx.Height ^ bx.Length ^ bx.Width;
这个 SO 答案解释了为什么 XOR 有时效果很好:Why are XOR often used in java hashCode() but another bitwise operators are used rarely?
注意:我不喜欢使用 xor 作为三个整数的哈希码的原因是:
a ^ b ^ a == b
换句话说,如果对哈希码有贡献的第一个整数和最后一个整数相同,则它们根本不会对最终哈希码有贡献 - 它们相互抵消,结果始终是中间整数。
如果你只使用两个整数,那就更糟了,因为:
a ^ a == 0
所以对于两个整数,对于它们相同的所有情况,哈希码都将为零。
【讨论】:
好的,谢谢!刚学这个,觉得很奇怪! 还值得注意的是,在越界整数算术是未定义行为的语言中,xor 运算符的优点是可以通过任何操作数组合产生已定义的行为,但在整数类型换行的语言中干净利落,加法同样快速简单,并且避免了您描述的问题案例。 那么如果我们可以保证整数列表是不同的,这是否可以被视为一种计算哈希码的好方法?【参考方案2】:你可能知道 GetHashCode() 是一个函数,它应该将你的对象映射到数字中,这样两个不同的对象获得相同数字的概率应该尽可能低(显然这个数字应该总是相同的相同的对象+函数应该很快)。从所有布尔运算符(AND、OR、NOT、XOR)中,XOR 提供最佳位分布(查看 OR、AND、XOR 布尔表)。但是我建议您检查这种方法:What is the best algorithm for an overridden System.Object.GetHashCode?。 (使用素数分布属性的散列函数)。
【讨论】:
以上是关于为啥在计算哈希码时使用 xor 运算符? [复制]的主要内容,如果未能解决你的问题,请参考以下文章