Search code examples
.netstringhashclrimplementation

Why does the `System.String.GetHasCode` return different values once I rerun my app?


Why does the System.String.GetHasCode return different values once I rerun my app?

E.g. I have the app:

using System;

namespace myprogram
{
    class Program {
        static void Main(string[] args) {
           Console.WriteLine("foo".GetHashCode());
        }
    }
}

I run the app twice and get the different outputs:

user@user MINGW64 /c/Projects/dotNet/Console.NET
$ dotnet run
1430600909

user@user MINGW64 /c/Projects/dotNet/Console.NET
$ dotnet run
208120252

Does that mean that the System.String.GetHasCode is implemented incorrectly in the .NET Core? Because according to the quote from the CLR via C# we have the following convention:

Objects with the same value should return the same code. For example, two String objects with the same text should return the same hash code value.

There is nothing about the app being run only once in the quote. I.e. I understand the quote with application to my case as follows: if the values of the two strings are equal, then the hash codes should be equal even after the app rerun.


Solution

  • The result of GetHashCode can be implementation dependent and is not guaranteed to be identical across multiple versions or platforms. For security purposes the .NET Core implementation uses a feature called "randomized string hashing" which creates different hash values for each application run.

    From the documentation (emphasis by me):

    The hash code itself is not guaranteed to be stable. Hash codes for identical strings can differ across .NET implementations, across .NET versions, and across .NET platforms (such as 32-bit and 64-bit) for a single version of .NET. In some cases, they can even differ by application domain. This implies that two subsequent runs of the same program may return different hash codes.

    The result is still stable within the same application run, in this example you will see three equal numbers printed:

    using System;
    
    public class Program
    {
        public static void Main()
        {
            Console.WriteLine("foo".GetHashCode());
            Console.WriteLine("foo".GetHashCode());
            Console.WriteLine("foo".GetHashCode());
        }
    }