// Use this if and only if 'Denial of Service' attacks are not a concern (i.e. never used for free-form user input), // or are otherwise mitigated internal unsafe int GetNonRandomizedHashCode() { fixed(char *src = &_firstChar) { Debug.Assert(src[this.Length] == '\0', "src[this.Length] == '\\0'"); Debug.Assert(((int)src) % 4 == 0, "Managed string should start at 4 bytes boundary"); uint hash1 = (5381 << 16) + 5381; uint hash2 = hash1; uint *ptr = (uint *)src; int length = this.Length; while (length > 2) { length -= 4; // Where length is 4n-1 (e.g. 3,7,11,15,19) this additionally consumes the null terminator hash1 = (BitOps.RotateLeft(hash1, 5) + hash1) ^ ptr[0]; hash2 = (BitOps.RotateLeft(hash2, 5) + hash2) ^ ptr[1]; ptr += 2; } if (length > 0) { // Where length is 4n-3 (e.g. 1,5,9,13,17) this additionally consumes the null terminator hash2 = (BitOps.RotateLeft(hash2, 5) + hash2) ^ ptr[0]; } return((int)(hash1 + (hash2 * 1566083941))); } }
private static void Block(ref uint rp0, ref uint rp1) { uint p0 = rp0; uint p1 = rp1; p1 ^= p0; p0 = BitOps.RotateLeft(p0, 20); p0 += p1; p1 = BitOps.RotateLeft(p1, 9); p1 ^= p0; p0 = BitOps.RotateLeft(p0, 27); p0 += p1; p1 = BitOps.RotateLeft(p1, 19); rp0 = p0; rp1 = p1; }
private static uint MixState(uint v1, uint v2, uint v3, uint v4) { return(BitOps.RotateLeft(v1, 1) + BitOps.RotateLeft(v2, 7) + BitOps.RotateLeft(v3, 12) + BitOps.RotateLeft(v4, 18)); }
private static uint QueueRound(uint hash, uint queuedValue) { return(BitOps.RotateLeft(hash + queuedValue * Prime3, 17) * Prime4); }
private static uint Round(uint hash, uint input) { return(BitOps.RotateLeft(hash + input * Prime2, 13) * Prime1); }