简体   繁体   English

对象是否可以使用64位gethashcode?

[英]Are 64 bit gethashcode available for objects?

I am using a dictionary and I want to overwrite the GetHashCode function of the Key. 我正在使用字典,并且想覆盖Key的GetHashCode函数。 But I need a 64-bit hashcode. 但是我需要一个64位哈希码。

Is there any solution? 有什么解决办法吗?

No, you can't. 不,你不能。 The signature of GetHashCode is fixed as virtual int GetHashCode() . GetHashCode的签名固定为virtual int GetHashCode()

Note that Dictionary<TKey, TValue> do handle multiple items with the same hashcode. 注意Dictionary<TKey, TValue> 确实使用相同的哈希码处理多个项目。 You can try it by overloading a GetHashCode like this: 您可以通过像这样重载GetHashCode来尝试:

public override GetHashCode()
{
    return 0;
}

That this will make the dictionary quite slow (it will make searching inside it O(n) instead of O(1))! 这样会使字典变慢(它将使在O(n)而不是O(1)的内部搜索)!

Dictionary<,> handles multiple objects with same key by looking at each one of the with the Equals method (so it's a two-step process, first GetHashCode , then Equals between all the items with the same GetHashCode ). Dictionary<,>通过使用Equals方法查看每个对象来处理具有相同键的多个对象(因此这是一个两步过程,首先是GetHashCode ,然后是所有具有相同GetHashCode的项目之间的Equals )。

To change a 64 bit GetHashCode to a 32 bit GetHashCode you can simply: 要将64位GetHashCode更改为32位GetHashCode,您可以简单地:

long hash64 = ....;
int hash32 = hash64.GetHashCode();
return hash32;

:-) :-)

or, if you prefer the long way: 或者,如果您更喜欢长途旅行:

long hash64 = ....;

unchecked
{
    int hash32 = ((int)hash64) ^ ((int)(hash64 >> 32));
    return hash32;
}

If you are interested, here it's explained how Dictionary<,> works internally. 如果您有兴趣, 这里说明Dictionary<,>在内部如何工作。 Look under The System.Collections.Generic.Dictionary Class The System.Collections.Generic.Dictionary Class下查看

I have done some research on Zobrist hashes... It seems that you should simply ignore the chances of collisions at 64 bits. 我已经对Zobrist散列进行了一些研究...看来您应该完全不理会64位碰撞的可能性。 If you want to simulate this, you could do something like: 如果要模拟此,可以执行以下操作:

public class HashPiece
{
    public readonly long Hash64;
    public readonly Piece[] Board = new Piece[64];

    public int GetHashCode()
    {
         return Hash64.GetHashCode();
    }

    public bool Equals(object other)
    {
        return this.Hash64 == ((HashPiece)other).Hash64;
    }
}

In this example you don't compare the Piece[] array, and you just hope the full 64 bit hash will be right. 在此示例中,您没有比较Piece[]数组,只是希望完整的64位哈希正确。 Clearly another solution is: 显然,另一个解决方案是:

    public bool Equals(object other)
    {
        HashPiece other2 = (HashPiece)other;

        if (this.Hash64 != other2.Hash64)
        {
            return false;
        }

        return this.Board.SequenceEqual(other.Board);
    }

Note that I've found anecdotical experience that the quality of the random number generator, and the single value of the seed value used, can influence the number of collisions. 请注意,我发现一种奇怪的经验 ,即随机数生成器的质量以及所使用的种子值的单个值会影响冲突次数。

I have used the below code to generate 64 Bit HashCode,mostly as a substitute for long repetitive strings. 我使用下面的代码生成64位HashCode,主要是用来代替长重复字符串。

 public long ComputeHash(String p_sInput)
 {
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        byte[] hash = md5.ComputeHash(Encoding.ASCII.GetBytes(p_sInput));
        return BitConverter.ToInt64(hash, 0);
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM