e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
64 lines
2.2 KiB
C#
64 lines
2.2 KiB
C#
// <copyright>
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
namespace System.ServiceModel
|
|
{
|
|
internal static class StringUtil
|
|
{
|
|
private static readonly bool randomizedStringHashingEnabled;
|
|
|
|
static StringUtil()
|
|
{
|
|
// StringComparer.InvariantCultureIgnoreCase.GetHashCode is a stable hash between 32 and 64 bits.
|
|
// Test the result of this GetHashCode against a known test vector to see if randomized hashing is enabled.
|
|
randomizedStringHashingEnabled = StringComparer.InvariantCultureIgnoreCase.GetHashCode("The quick brown fox jumps over the lazy dog.") != 0x703e662e;
|
|
}
|
|
|
|
// This should be used instead of String.GetHashCode if the value should be
|
|
// stable even if UseRandomizedStringHashing is enabled.
|
|
internal static int GetNonRandomizedHashCode(string str)
|
|
{
|
|
if (!randomizedStringHashingEnabled)
|
|
{
|
|
return str.GetHashCode();
|
|
}
|
|
|
|
return GetStableHashCode(str);
|
|
}
|
|
|
|
// This is copied from the 32 bit implementation from String.GetHashCode.
|
|
// Since ServiceModel is compiled for MSIL, we can't have different functionality
|
|
// for 32 and 64 bits.
|
|
[System.Security.SecuritySafeCritical]
|
|
private static int GetStableHashCode(string str)
|
|
{
|
|
unsafe
|
|
{
|
|
fixed (char* src = str)
|
|
{
|
|
int hash1 = (5381 << 16) + 5381;
|
|
int hash2 = hash1;
|
|
|
|
// 32 bit machines.
|
|
int* pint = (int*)src;
|
|
int len = str.Length;
|
|
while (len > 2)
|
|
{
|
|
hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0];
|
|
hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ pint[1];
|
|
pint += 2;
|
|
len -= 4;
|
|
}
|
|
|
|
if (len > 0)
|
|
{
|
|
hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0];
|
|
}
|
|
|
|
return hash1 + (hash2 * 1566083941);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|