为什么xor运算符用于计算哈希码?

时间:2013-10-02 14:22:04

标签: c# .net

在这篇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();
    }
}

我不明白行hCode = bx.Height ^ bx.Length ^ bx.Width;

有人可以解释一下吗?为什么xor?

2 个答案:

答案 0 :(得分:7)

^运算符是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

换句话说,如果对哈希码有贡献的第一个和最后一个int是相同的,它们根本不会对最终的哈希码有所贡献 - 它们相互抵消,结果总是中间的int。

如果你只使用两个整数,那就更糟了,因为:

a ^ a == 0

因此,对于两个整数,对于它们相同的所有情况,哈希码将为零。

答案 1 :(得分:0)

你可能知道GetHashCode()是一个函数,它应该将你的对象映射到数字中,这样两个不同对象得到相同数字的概率应该尽可能少(显然这个数字应该总是相同的相同的对象+功能应该很快)。从所有布尔运算符(AND,OR,NOT,XOR)开始,XOR给出最佳位分布(查看OR,AND,XOR布尔表)。不过,我建议您检查一下这种方法:What is the best algorithm for an overridden System.Object.GetHashCode?。 (使用素数分布属性的哈希函数)。