<p>Is the return value of GetHashCode() guaranteed to be consistent assuming the same string value is being used? (C#/ASP.NET)</p>

<p>I uploaded my code to a server today and to my surprise I had to reindex some data because my server (win2008 64-bit) was returning different values compared to my desktop computer.</p>

[{'answer_id': 53088, 'author': 'Jonas', 'author_id': 5480, 'author_profile': 'https://Stackoverflow.com/users/5480', 'pm_score': 6, 'selected': True, 'text': "<p>If I'm not mistaken, GetHashCode is consistent given the same value, but it is NOT guaranteed to be consistent across different versions of the framework.</p>\n\n<p>From the MSDN docs on String.GetHashCode():</p>\n\n<blockquote>\n  <p>The behavior of GetHashCode is dependent on its implementation, which might change from one version of the common language runtime to another. A reason why this might happen is to improve the performance of GetHashCode. </p>\n</blockquote>\n"}, {'answer_id': 53248, 'author': 'public static', 'author_id': 1368, 'author_profile': 'https://Stackoverflow.com/users/1368', 'pm_score': 0, 'selected': False, 'text': '<p>I wonder if there are differences between 32-bit and 64-bit operating systems, because I am certain both my server and home computer are running the same version of .NET</p>\n\n<p>I was always weary of using GetHashCode(), it might be a good idea for me to simply role my own hash algorithm.  Well at least I ended up writing a quick re-index .aspx page because of it.</p>\n'}, {'answer_id': 53323, 'author': 'Mark Brackett', 'author_id': 2199, 'author_profile': 'https://Stackoverflow.com/users/2199', 'pm_score': 0, 'selected': False, 'text': '<p>Are you running Win2008 x86 as your desktop? Because Win2008 includes version <a href="http://www.ditii.com/2008/02/16/windows-server-2008-windows-vista-sp1-net-framework-source-symbols/" rel="nofollow noreferrer">2.0.50727.1434</a>, which is an updated version of 2.0 included in Vista RTM.</p>\n'}, {'answer_id': 53548, 'author': 'johnc', 'author_id': 5302, 'author_profile': 'https://Stackoverflow.com/users/5302', 'pm_score': 0, 'selected': False, 'text': "<p>Not a direct answer to your question, which Jonas has answered well, however this may be of assistance if you are worried about equality testing in hashes</p>\n\n<p>From our tests, depending on what you are requiring with hashcodes, in C#, hashcodes do not need to be unique for Equality operations.  As an example, consider the following:</p>\n\n<p>We had a requirement to overload the equals operator, and therefore the GetHashCode function of our objects as they had become volatile and stateless, and sourcing themselves directly from data, so in one place of the application we needed to ensure that an object would be viewed as equal to another object <em>if it was sourced from the same data</em>, not just if it was the same reference. Our unique data identifiers are Guids.</p>\n\n<p>The equals operator was easy to cater for as we just checked on the Guid of the record (after checking for null).</p>\n\n<p>Unfortuantely the HashCode data size (being an int) depends on the operating system, and on our 32 bit system, the hashcode would be 32 bit. Mathematically, when we override the GetHashCode function, it is impossible to generate a unique hashcode from a guid which is greater than 32 bit (look at it from the converse, how would you translate a 32 bit integer into a guid?).</p>\n\n<p>We then did some tests where we took the Guid as a string and returned the HashCode of the Guid, which almost always returns a unique identifier in our tests, but not always.</p>\n\n<p>What we did notice however, when an object is in a hashed collection object (a hashtable, a dictionary etc), when 2 objects are not unique but their hashcodes are, the hashcode is only used as a first option lookup, if there are non-unique hash codes being used, <em>the equality operator is always used as a fall back to detirmine equality</em>.</p>\n\n<p>As I said this may or may not be relevant to your situation, but if it is it's a handy tip.</p>\n\n<p><strong>UPDATE</strong></p>\n\n<p>To demonstrate, we have a Hashtable:</p>\n\n<p>Key:Object A (Hashcode 1), value Object A1</p>\n\n<p>Key:Object B (Hashcode 1), value Object B1</p>\n\n<p>Key:Object C (Hashcode 1), value Object C1</p>\n\n<p>Key:Object D (Hashcode 2), value Object D1</p>\n\n<p>Key:Object E (Hashcode 3), value Object E1</p>\n\n<p>When I call the hashtable for the object with the key of Object A, the object A1 will be returned after 2 steps, a call for hashcode 1, then an equality check on the key object as there is not a unique key with the hashcode 1</p>\n\n<p>When I call the hashtable for the object with the key of Object D, the object D1 will be returned after 1 step, a hash lookup</p>\n"}, {'answer_id': 53622, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<blockquote>\n  <p>What we did notice however, when an\n  object is in a hashed collection\n  object (a hashtable, a dictionary\n  etc), when 2 objects are not unique\n  but their hashcodes are, the hashcode\n  is only used as a first option lookup,\n  if there are non-unique hash codes\n  being used, the equality operator is\n  always used as a fall back to\n  detirmine equality.</p>\n</blockquote>\n\n<p>This is the way hash lookups work, right? Each bucket contains a list of items having the same hash code.</p>\n\n<p>So to find the correct item under these conditions a linear search using value equality comparison takes place.</p>\n\n<p>And if your hashing implementation achieves good distribution, this search is not required, i.e., one item per bucket.</p>\n\n<p>Is my understanding correct? </p>\n'}, {'answer_id': 565370, 'author': 'Jack Bolding', 'author_id': 5882, 'author_profile': 'https://Stackoverflow.com/users/5882', 'pm_score': 3, 'selected': False, 'text': '<p>The implementation is dependent on the version of the framework but it also depends on the <a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=344006" rel="noreferrer">architecture</a>.  The implementation of string.GetHashCode() is dfferent in the x86 and x64 versions of the framework even if they have the same version number.  </p>\n'}, {'answer_id': 835571, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 4, 'selected': False, 'text': '<p>I had a similar problem where I filled a database table with information which was dependent on String.GetHashCode (Not the best idea) and when I upgraded the server I was working on to x64 I noticed the values I was getting from String.GetHashCode were inconsistent with what was already in the table. My solution was to use my own version of GetHashCode which returns the same value as String.GetHashCode on a x86 framework.</p>\n\n<p>Here\'s the code, don\'t forget to compile with "Allow unsafe code":</p>\n\n<pre><code>    /// &lt;summary&gt;\n    /// Similar to String.GetHashCode but returns the same as the x86 version of String.GetHashCode for x64 and x86 frameworks.\n    /// &lt;/summary&gt;\n    /// &lt;param name="s"&gt;&lt;/param&gt;\n    /// &lt;returns&gt;&lt;/returns&gt;\n    public static unsafe int GetHashCode32(string s)\n    {\n        fixed (char* str = s.ToCharArray())\n        {\n            char* chPtr = str;\n            int num = 0x15051505;\n            int num2 = num;\n            int* numPtr = (int*)chPtr;\n            for (int i = s.Length; i &gt; 0; i -= 4)\n            {\n                num = (((num &lt;&lt; 5) + num) + (num &gt;&gt; 0x1b)) ^ numPtr[0];\n                if (i &lt;= 2)\n                {\n                    break;\n                }\n                num2 = (((num2 &lt;&lt; 5) + num2) + (num2 &gt;&gt; 0x1b)) ^ numPtr[1];\n                numPtr += 2;\n            }\n            return (num + (num2 * 0x5d588b65));\n        }\n    }\n</code></pre>\n'}, {'answer_id': 1738613, 'author': 'greg', 'author_id': 211600, 'author_profile': 'https://Stackoverflow.com/users/211600', 'pm_score': -1, 'selected': False, 'text': "<p>I would have to Say...you cannot rely on it.  For example if I run file1 through c#'s md5 hash code and copy nd paste the same file to a new directory...the hash code come out different even tough it is he same file.  Obviously its the same .net version, same everything.  The only thing that changed was the path.</p>\n"}, {'answer_id': 18352165, 'author': 'Sasha', 'author_id': 91495, 'author_profile': 'https://Stackoverflow.com/users/91495', 'pm_score': 0, 'selected': False, 'text': '<pre><code>    /// &lt;summary&gt;\n    /// Default implementation of string.GetHashCode is not consistent on different platforms (x32/x64 which is our case) and frameworks. \n    /// FNV-1a - (Fowler/Noll/Vo) is a fast, consistent, non-cryptographic hash algorithm with good dispersion. (see http://isthe.com/chongo/tech/comp/fnv/#FNV-1a)\n    /// &lt;/summary&gt;\n    private static int GetFNV1aHashCode(string str)\n    {\n        if (str == null)\n            return 0;\n        var length = str.Length;\n        // original FNV-1a has 32 bit offset_basis = 2166136261 but length gives a bit better dispersion (2%) for our case where all the strings are equal length, for example: "3EC0FFFF01ECD9C4001B01E2A707"\n        int hash = length;\n        for (int i = 0; i != length; ++i)\n            hash = (hash ^ str[i]) * 16777619;\n        return hash;\n    }\n</code></pre>\n\n<p>This implementation can be slower than the unsafe one posted before. But much simpler and safe.</p>\n'}]
['https://Stackoverflow.com/questions/53086', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1368/']