File: src\libraries\Common\src\System\HashCodeRandomization.cs
Web Access
Project: src\src\libraries\System.Security.Cryptography.Cose\src\System.Security.Cryptography.Cose.csproj (System.Security.Cryptography.Cose)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
namespace System
{
    // Contains helpers for calculating randomized hash codes of common types.
    // Since these hash codes are randomized, callers must not persist them between
    // AppDomain restarts. There's still the potential for limited collisions
    // if two distinct types have the same bit pattern (e.g., string.Empty and (int)0).
    // This should be acceptable because the number of practical collisions is
    // limited by the number of distinct types used here, and we expect callers to
    // have a small, fixed set of accepted types for any hash-based collection.
    // If we really do need to address this in the future, we can use a seed per type
    // rather than a global seed for the entire AppDomain.
    internal static class HashCodeRandomization
    {
        public static int GetRandomizedOrdinalHashCode(this string value)
        {
#if NET
            // In .NET Core, string hash codes are already randomized.
 
            return value.GetHashCode();
#else
            // Downlevel, we need to perform randomization ourselves. There's still
            // the potential for limited collisions ("Hello!" and "Hello!\0"), but
            // this shouldn't be a problem in practice. If we need to address it,
            // we can mix the string length into the accumulator before running the
            // string contents through.
            //
            // We'll pull out pairs of chars and write 32 bits at a time.
 
            HashCode hashCode = default;
            int pair = 0;
            for (int i = 0; i < value.Length; i++)
            {
                int ch = value[i];
                if ((i & 1) == 0)
                {
                    pair = ch << 16; // first member of pair
                }
                else
                {
                    pair |= ch; // second member of pair
                    hashCode.Add(pair); // write pair as single unit
                    pair = 0;
                }
            }
            hashCode.Add(pair); // flush any leftover data (could be 0 or 1 chars)
            return hashCode.ToHashCode();
#endif
        }
 
        public static int GetRandomizedHashCode(this int value)
        {
            return HashCode.Combine(value);
        }
    }
}