GetHashCode() gives different results on different servers?
Asked Answered
F

4

18

I declared a C# line of code like so

int hashcode = "apple".GetHashCode();

On my computer, a computer at work, and a friend's computer, the result was 1657858284. On a development server, the result was 1548091822. Is there a way for me to tell the project to always make GetHashCode() yield 1657858284, regardless of which server it is on?

more notes At first, i noticed there was a difference in versions...the 1657858284 results came from .NET 3.5 and .NET 4.0. The 1548091822 came from .NET 2.0.

I then told visual studios 2010 to compile project as a .net 2.0 project, but it still gave me 1657858284.

Fusible answered 24/5, 2011 at 17:59 Comment(5)
So, what's the difference between the computers? Different .NET version, maybe?Commendam
[From MSDN] (msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx) "the .NET Framework does not guarantee the default implementation of the GetHashCode method, and the value it returns will be the same between different versions of the .NET Framework."Inefficiency
From my understanding GetHashCode is only used to serve as a lookup key for example for hashmaps. So I am not sure you can expect GetHashCode() to produce similar results. I believe however that you can override GetHashCode()Federation
Saunders - ok, added more detialsFusible
You should read: blogs.msdn.com/b/ericlippert/archive/2011/02/28/… Specifically: "Consumers of GetHashCode cannot rely upon it being stable over time or across appdomains"Kistler
F
17

It's possible that you're using 2 different versions of .Net. This behavior is noted on the MSDN article:
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx
From the remarks:

The default implementation of the GetHashCode method does not guarantee unique return values for different objects. Furthermore, the .NET Framework does not guarantee the default implementation of the GetHashCode method, and the value it returns will be the same between different versions of the .NET Framework. Consequently, the default implementation of this method must not be used as a unique object identifier for hashing purposes.

Frostwork answered 24/5, 2011 at 18:4 Comment(0)
M
30

As others have noted, that is in accordance with the documentation. You must not rely on GetHashCode returning the same thing, ever. The only invariant you can rely upon is that it will return the same value on the same object in the same appdomain if the object has not been mutated in any way that changes its equality semantics. If any of those conditions are not met -- if the two objects are in different appdomains, or the object was mutated in a way that changes its equality semantics -- then you have no guarantee whatsoever that "identical" objects will return the same hash code.

The only thing you should be using a hash code for is to balance a hash table. Any other usage is "off label" and at your own risk. Don't do it. If you need a stable string hash that works across arbitrary boundaries then use an industry standard algorithm like SHA256 or something.

See my archive of articles about hashing issues for more details if this subject interests you:

http://blogs.msdn.com/b/ericlippert/archive/tags/hashing/

Mandi answered 24/5, 2011 at 18:14 Comment(0)
F
17

It's possible that you're using 2 different versions of .Net. This behavior is noted on the MSDN article:
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx
From the remarks:

The default implementation of the GetHashCode method does not guarantee unique return values for different objects. Furthermore, the .NET Framework does not guarantee the default implementation of the GetHashCode method, and the value it returns will be the same between different versions of the .NET Framework. Consequently, the default implementation of this method must not be used as a unique object identifier for hashing purposes.

Frostwork answered 24/5, 2011 at 18:4 Comment(0)
P
2

For your custom classes to return a stable hash code you should override the GetHashCode() method or else the GetHashCode method of the Object class will be used, which I think can vary a lot. (Might even be instance specific).

Pomatum answered 24/5, 2011 at 18:6 Comment(0)
F
1

If you need to have a checksum that e.g. allows you to quickly verify data integrity in transport, simply run it through a (cryptographic) hash with appropriate number of bits, as

- MD5
- SHA256
- SHA1
- fletcher

.Net's GetHashCode is not meant to identify anything (32 bits is going to result in collisions very soon anyway, which is why you can't use it to identify string anyway.)

Note that even the above four will allow collisions (but less soon); so be sure to only use it as a checksum, not identification.

Flunkey answered 1/6, 2011 at 23:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.