我正在使用字典,我想覆盖密钥的GetHashCode
功能。但我需要一个64位哈希码。
有没有解决方案?
答案 0 :(得分:4)
GetHashCode
的签名固定为virtual int GetHashCode()
。
请注意,Dictionary<TKey, TValue>
执行处理具有相同哈希码的多个项目。您可以通过重载这样的GetHashCode来尝试它:
public override GetHashCode()
{
return 0;
}
这会使字典变得非常慢(它会在其中搜索O(n)而不是O(1))!
Dictionary<,>
通过使用Equals
方法查看每个对象来处理具有相同键的多个对象(因此这是一个两步过程,首先是GetHashCode
,然后是{{1}在具有相同Equals
)的所有项目之间。
要将64位GetHashCode更改为32位GetHashCode,您可以简单地:
GetHashCode
:-)
或者,如果你更喜欢漫长的道路:
long hash64 = ....;
int hash32 = hash64.GetHashCode();
return hash32;
如果您有兴趣,here会解释long hash64 = ....;
unchecked
{
int hash32 = ((int)hash64) ^ ((int)(hash64 >> 32));
return hash32;
}
内部如何运作。查看Dictionary<,>
我对Zobrist哈希进行了一些研究......看起来你应该忽略64位冲突的可能性。如果你想模拟这个,你可以做类似的事情:
The System.Collections.Generic.Dictionary Class
在这个例子中,你不比较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;
}
}
数组,你只希望完整的64位哈希是正确的。显然,另一个解决方案是:
Piece[]
请注意,我发现anecdotical experience随机数生成器的质量以及所使用的种子值的单个值会影响碰撞次数。
答案 1 :(得分:1)
我使用下面的代码生成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);
}