1

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

String.GetHashCode() for identical strings can differ because of:

  1. Different versions of .NET Framework.

  2. Different platforms (such as 32-bit and 64-bit).

  3. Or even different application domains.

How about Guid.GetHashCode()? Will it change in above 3 situations?

I have checked that for 2, Guid.GetHashCode() does return different values.

Update

How to understand 3 regarding String.GetHashCode()? Suppose I run the same application twice, there are definitely 2 different application domains. But as I tried, the hash code are the always same as long as the target platform doesn't change. For example, "hello, world".GetHashCode().

So when could 3 happen?

And here is some of my problem context:

My server application receives some GUIDs from clients. The GUID is unique for each client. I want to distribute the client to different buckets. And I need to keep the client-bucket mapping fixed. There are many clients so I cannot keep all the seen clients in memory.

My current solution is:

  1. Get the hash code of the client GUID (GUID or GUID string, not decided yet).
  2. Use the (HashCode % bucket total number) as the bucket index.

I have to make sure the hash code stay fixed for a specific client.

smwikipedia
  • 61,609
  • 92
  • 309
  • 482
  • 1
    Why do you need to know this? Why does it matter if the same code, executed on 32-bit and 64-bit, gives different hash codes? – Lasse V. Karlsen Sep 02 '14 at 07:32
  • No it doesn't. Your 2. test is unlikely to be correct, the second time you run it you'll get a different guid :) Its implementation [is very simple](http://referencesource.microsoft.com/#q=guid.gethashcode). String.GetHashCode() got lots of extra attention because it is so often used and has security implications. [Details here](http://stackoverflow.com/a/15176541/17034). – Hans Passant Sep 02 '14 at 08:16
  • If you need a reliable hashcode implementation that isn't impacted by changes outside of your control, you should implement one yourself. `GetHashCode` is explicitly documented not to be persisted and as such you cannot trust that the calculation will stay the same. A meager .NET hotfix might change it beneath your application. – Lasse V. Karlsen Sep 03 '14 at 06:39

3 Answers3

3

The GetHashCode method, as inherited from System.Object comes with this message in the documentation:

A hash code is intended for efficient insertion and lookup in collections that are based on a hash table. A hash code is not a permanent value. For this reason:
* Do not serialize hash code values or store them in databases.
* Do not use the hash code as the key to retrieve an object from a keyed collection.
* Do not send hash codes across application domains or processes. In some cases, hash codes may be computed on a per-process or per-application domain basis.
* Do not use the hash code instead of a value returned by a cryptographic hashing function if you need a cryptographically strong hash. For cryptographic hashes, use a class derived from the System.Security.Cryptography.HashAlgorithm or System.Security.Cryptography.KeyedHashAlgorithm class.
* Do not test for equality of hash codes to determine whether two objects are equal. (Unequal objects can have identical hash codes.) To test for equality, call the ReferenceEquals or Equals method.

(my emphasis)

So regardless of whether it actually, currently, returns different values or not, you should assume it can.

As for your 3 specific cases, the answers to those are:

  1. It may
  2. It may
  3. It may

And that's the whole point.

In short, if you need a reliable hashcode implementation for your strings or guids or whatever, that can be persisted, and will not be impacted by the things listed (or anything else outside of your control), then you need to implement it yourself.

You could implement IEqualityComparer<T>, most .NET collections that use hashcodes for keying can be provided a custom object implementing that interface, and thus you can provide your own hashcode implementation even for those.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
1

The other answers are completely right - since it isn't documented, you shouldn't rely on the hash-code of a GUID being consistent across multiple application domains.

That said, in the interests of idle curiousity, here's the implementation being used (from Reference Source), which in fact does seem to be a stable implementation that only uses the bytes comprising the GUID:

public override int GetHashCode()
{
    return _a ^ (((int)_b << 16) | (int)(ushort)_c) ^ (((int)_f << 24) | _k);
}
Ani
  • 111,048
  • 26
  • 262
  • 307
0

The documentation for Guid.GetHashCode is pretty bare; it doesn't define how the hash code is calculated. Therefore you should assume that all the warnings for Object.GetHashCode apply.

Peter O.
  • 32,158
  • 14
  • 82
  • 96