Can I depend on the values of GetHashCode() to be consistent?

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

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.


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.

From the MSDN docs on String.GetHashCode():

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.


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.

Here's the code, don't forget to compile with "Allow unsafe code":

    /// <summary>
    /// Similar to String.GetHashCode but returns the same as the x86 version of String.GetHashCode for x64 and x86 frameworks.
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static unsafe int GetHashCode32(string s)
    {
        fixed (char* str = s.ToCharArray())
        {
            char* chPtr = str;
            int num = 0x15051505;
            int num2 = num;
            int* numPtr = (int*)chPtr;
            for (int i = s.Length; i > 0; i -= 4)
            {
                num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
                if (i <= 2)
                {
                    break;
                }
                num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
                numPtr += 2;
            }
            return (num + (num2 * 0x5d588b65));
        }
    }