The following accurately reproduces the default String
hash codes on .NET 4.7 (and probably earlier). This is the hash code specified:
- The default value for the
String
instance: "abc".GetHashCode()
StringComparer.Ordinal.GetHashCode("abc")
- Various
String
methods that accept an enumeration of StringComparison.Ordinal
. System.Globalization.CompareInfo.GetStringComparer(CompareOptions.Ordinal)
Testing releases with full JIT optimizations, these versions are modestly superior to the built-in .NET code and have also been heavily tested for exact equivalence with .NET
behavior. Note that there are separate versions for x86 and x64. Your program should include how; below the relevant codelists is a wiring harness that selects the appropriate version at runtime.
x86 - (.NET works in 32-bit mode)
static unsafe int GetHashCode_x86_NET(int* p, int c) { int h1, h2 = h1 = 0x15051505; while (c > 2) { h1 = ((h1 << 5) + h1 + (h1 >> 27)) ^ *p++; h2 = ((h2 << 5) + h2 + (h2 >> 27)) ^ *p++; c -= 4; } if (c > 0) h1 = ((h1 << 5) + h1 + (h1 >> 27)) ^ *p++; return h1 + (h2 * 0x5d588b65); }
x64 - (.NET runs in 64-bit mode)
static unsafe int GetHashCode_x64_NET(Char* p) { int h1, h2 = h1 = 5381; while (*p != 0) { h1 = ((h1 << 5) + h1) ^ *p++; if (*p == 0) break; h2 = ((h2 << 5) + h2) ^ *p++; } return h1 + (h2 * 0x5d588b65); }
Call / extension method for any platform (x86 / x64):
readonly static int _hash_sz = IntPtr.Size == 4 ? 0x2d2816fe : 0x162a16fe; public static unsafe int GetStringHashCode(this String s) {
source share