Guid.GetHashCode()会使用不同的AppDomain返回不同的值吗?

时间:2014-09-02 03:19:35

标签: .net hash

根据MSDN:http://msdn.microsoft.com/en-us/library/system.string.gethashcode%28v=vs.110%29.aspx

相同字符串的String.GetHashCode()因以下原因而有所不同:

  1. 不同版本的.NET Framework。

  2. 不同的平台(例如32位和64位)。

  3. 甚至是不同的应用领域。

  4. Guid.GetHashCode()怎么样?它会在以上三种情况下发生变化吗?

    我已经检查过2,Guid.GetHashCode()会返回不同的值。

    更新

    如何理解有关String.GetHashCode()的3?假设我运行两次相同的应用程序,肯定有2个不同的应用程序域。但是,正如我所尝试的那样,只要目标平台没有改变,哈希码就总是相同的。例如," hello,world" .GetHashCode()。

    那么什么时候会发生?

    以下是我的一些问题背景:

    我的服务器应用程序从客户端接收一些GUID。 GUID对每个客户端都是唯一的。我想将客户端分发到不同的存储区。我需要保持客户端映射映射不变。有很多客户,所以我无法将所有看到的客户留在记忆中。

    我目前的解决方案是:

    1. 获取客户端GUID的哈希码(GUID或GUID字符串,尚未确定)。
    2. 使用(HashCode%存储桶总数)作为存储区索引。
    3. 我必须确保哈希码对于特定客户端保持固定。

3 个答案:

答案 0 :(得分:3)

继承自GetHashCode的{​​{1}}方法在documentation中附带此消息:

  

哈希代码用于在基于哈希表的集合中进行有效插入和查找。哈希码不是永久值。出于这个原因:
  * 不要序列化哈希码值或将它们存储在数据库中。
  *不要使用哈希码作为从密钥集合中检索对象的密钥   * 不要跨应用程序域或进程发送哈希码。在某些情况下,可以基于每个进程或每个应用程序域计算哈希码。
  *如果需要加密强哈希,请不要使用哈希码而不是加密哈希函数返回的值。对于加密哈希,请使用从System.Security.Cryptography.HashAlgorithm或System.Security.Cryptography.KeyedHashAlgorithm类派生的类。
  *不要测试哈希码的相等性来确定两个对象是否相等。 (不等的对象可以具有相同的哈希码。)要测试相等性,请调用ReferenceEquals或Equals方法。

(我的重点)

因此无论当前是否实际返回不同的值,您都应该认为它可以。

至于你的3个具体案例,答案是:

  1. 可能
  2. 可能
  3. 可能
  4. 这就是重点

    简而言之,如果你需要一个可靠的哈希码实现你的字符串或guids或其他什么,可以持久化,并且不会受列出的东西(或你控制之外的任何其他东西)的影响,那么你需要实现你自己。

    您可以实现IEqualityComparer<T>,大多数使用哈希码进行键控的.NET集合都可以提供实现该接口的自定义对象,因此您甚至可以提供自己的哈希码实现。

答案 1 :(得分:1)

其他答案完全正确 - 由于没有记录,您不应该依赖GUID的哈希码在多个应用程序域中保持一致。

那就是说,为了空闲的好奇,这里使用的是实现(来自Reference Source),实际上 似乎只是一个稳定的实现使用包含GUID的字节:

public override int GetHashCode()
{
    return _a ^ (((int)_b << 16) | (int)(ushort)_c) ^ (((int)_f << 24) | _k);
}

答案 2 :(得分:0)

Guid.GetHashCode的文档非常简单;它没有定义如何计算哈希码。因此,您应该假设Object.GetHashCode的所有警告都适用。