簡體   English   中英

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

[英]Are 64 bit gethashcode available for objects?

我正在使用字典,並且想覆蓋Key的GetHashCode函數。 但是我需要一個64位哈希碼。

有什么解決辦法嗎?

不,你不能。 GetHashCode的簽名固定為virtual int GetHashCode()

注意Dictionary<TKey, TValue> 確實使用相同的哈希碼處理多個項目。 您可以通過像這樣重載GetHashCode來嘗試:

public override GetHashCode()
{
    return 0;
}

這樣會使字典變慢(它將使在O(n)而不是O(1)的內部搜索)!

Dictionary<,>通過使用Equals方法查看每個對象來處理具有相同鍵的多個對象(因此這是一個兩步過程,首先是GetHashCode ,然后是所有具有相同GetHashCode的項目之間的Equals )。

要將64位GetHashCode更改為32位GetHashCode,您可以簡單地:

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

:-)

或者,如果您更喜歡長途旅行:

long hash64 = ....;

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

如果您有興趣, 這里說明Dictionary<,>在內部如何工作。 The System.Collections.Generic.Dictionary Class下查看

我已經對Zobrist散列進行了一些研究...看來您應該完全不理會64位碰撞的可能性。 如果要模擬此,可以執行以下操作:

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;
    }
}

在此示例中,您沒有比較Piece[]數組,只是希望完整的64位哈希正確。 顯然,另一個解決方案是:

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

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

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

請注意,我發現一種奇怪的經驗 ,即隨機數生成器的質量以及所使用的種子值的單個值會影響沖突次數。

我使用下面的代碼生成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