static internal ulong InternalDigestState64(State64 state) { InputTextStream p = new InputTextStream(state.mem64); long bEnd = state.memsize; ulong h64; if (state.total_len >= 32) { ulong v1 = state.v1; ulong v2 = state.v2; ulong v3 = state.v3; ulong v4 = state.v4; h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); h64 = XXH64_mergeRound(h64, v1); h64 = XXH64_mergeRound(h64, v2); h64 = XXH64_mergeRound(h64, v3); h64 = XXH64_mergeRound(h64, v4); } else { h64 = state.v3 + PRIME64_5; } h64 += state.total_len; while (p.Position + 8 <= bEnd) { ulong k1 = XXH64_round(0, p.ReadUInt64()); h64 ^= k1; h64 = XXH_rotl64(h64, 27) * PRIME64_1 + PRIME64_4; } if (p.Position + 4 <= bEnd) { h64 ^= (ulong)(p.ReadUInt32()) * PRIME64_1; h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; } while (p.Position < bEnd) { h64 ^= p.ReadByte() * PRIME64_5; h64 = XXH_rotl64(h64, 11) * PRIME64_1; } h64 ^= h64 >> 33; h64 *= PRIME64_2; h64 ^= h64 >> 29; h64 *= PRIME64_3; h64 ^= h64 >> 32; return(h64); }
internal static uint InternalDigestState32(State32 state) { var p = new InputTextStream(state.mem32); long bEnd = state.memsize; uint h32; if (state.total_len >= 16) { h32 = XXH_rotl32(state.v1, 1) + XXH_rotl32(state.v2, 7) + XXH_rotl32(state.v3, 12) + XXH_rotl32(state.v4, 18); } else { h32 = state.seed + PRIME32_5; } h32 += (uint)state.total_len; while (p.Position + 4 <= bEnd) { h32 += p.ReadUInt32() * PRIME32_3; h32 = XXH_rotl32(h32, 17) * PRIME32_4; } while (p.Position < bEnd) { h32 += p.ReadByte() * PRIME32_5; h32 = XXH_rotl32(h32, 11) * PRIME32_1; } h32 ^= h32 >> 15; h32 *= PRIME32_2; h32 ^= h32 >> 13; h32 *= PRIME32_3; h32 ^= h32 >> 16; return(h32); }
static public ulong XXH64(byte[] input, int offset, int length, ulong seed) { if (input == null) { throw new ArgumentNullException("input"); } if (input.Rank != 1) { ThrowArrayMultiRank("input"); } if (input.GetLowerBound(0) != 0) { ThrowArrayNonZeroLowerBound("input"); } if (offset < 0) { ThrowArgumentNonNegativeNumber("offset"); } if (length < 0) { ThrowArgumentNonNegativeNumber("length"); } if (input.Length < (offset + length)) { ThrowArrayInvalidOffsetAndLength(); } #if EnableSimpleVersion /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ State64 state = new State64(); ResetState64(state, seed); UpdateState64(state, input, offset, length); return(DigestState64(state)); #else InputTextStream p = new InputTextStream(input, offset); long bEnd = p.Position + length; ulong h64; if (length >= 32) { long limit = bEnd - 32; ulong v1 = seed + PRIME64_1 + PRIME64_2; ulong v2 = seed + PRIME64_2; ulong v3 = seed + 0; ulong v4 = seed - PRIME64_1; do { v1 += p.ReadUInt64() * PRIME64_2; v1 = XXH_rotl64(v1, 31); v1 *= PRIME64_1; v2 += p.ReadUInt64() * PRIME64_2; v2 = XXH_rotl64(v2, 31); v2 *= PRIME64_1; v3 += p.ReadUInt64() * PRIME64_2; v3 = XXH_rotl64(v3, 31); v3 *= PRIME64_1; v4 += p.ReadUInt64() * PRIME64_2; v4 = XXH_rotl64(v4, 31); v4 *= PRIME64_1; }while (p.Position <= limit); h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); v1 *= PRIME64_2; v1 = XXH_rotl64(v1, 31); v1 *= PRIME64_1; h64 ^= v1; h64 = h64 * PRIME64_1 + PRIME64_4; v2 *= PRIME64_2; v2 = XXH_rotl64(v2, 31); v2 *= PRIME64_1; h64 ^= v2; h64 = h64 * PRIME64_1 + PRIME64_4; v3 *= PRIME64_2; v3 = XXH_rotl64(v3, 31); v3 *= PRIME64_1; h64 ^= v3; h64 = h64 * PRIME64_1 + PRIME64_4; v4 *= PRIME64_2; v4 = XXH_rotl64(v4, 31); v4 *= PRIME64_1; h64 ^= v4; h64 = h64 * PRIME64_1 + PRIME64_4; } else { h64 = seed + PRIME64_5; } h64 += (ulong)length; while (p.Position + 8 <= bEnd) { ulong k1 = p.ReadUInt64(); k1 *= PRIME64_2; k1 = XXH_rotl64(k1, 31); k1 *= PRIME64_1; h64 ^= k1; h64 = XXH_rotl64(h64, 27) * PRIME64_1 + PRIME64_4; } if (p.Position + 4 <= bEnd) { h64 ^= (ulong)(p.ReadUInt32()) * PRIME64_1; h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; } while (p.Position < bEnd) { h64 ^= p.ReadByte() * PRIME64_5; h64 = XXH_rotl64(h64, 11) * PRIME64_1; } h64 ^= h64 >> 33; h64 *= PRIME64_2; h64 ^= h64 >> 29; h64 *= PRIME64_3; h64 ^= h64 >> 32; return(h64); #endif }
/* * XXH32() : * Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". * The memory between offset & offset+length in "input" must be valid (allocated and read-accessible). * "seed" can be used to alter the result predictably. * * Original C implementation definition: * unsigned int XXH32 (const void* input, size_t length, unsigned seed); * * XXH64() : * Calculate the 64-bits hash of sequence "length" bytes stored at memory address "input". * Faster on 64-bits systems. Slower on 32-bits systems. * * Original C implementation definition: * unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed); */ static public uint XXH32(byte[] input, int offset, int length, uint seed) { if (input == null) { throw new ArgumentNullException("input"); } if (input.Rank != 1) { ThrowArrayMultiRank("input"); } if (input.GetLowerBound(0) != 0) { ThrowArrayNonZeroLowerBound("input"); } if (offset < 0) { ThrowArgumentNonNegativeNumber("offset"); } ; if (length < 0) { ThrowArgumentNonNegativeNumber("length"); } if (input.Length < (offset + length)) { ThrowArrayInvalidOffsetAndLength(); } #if EnableSimpleVersion /* Simple version, good for code maintenance, but unfortunately slow for small inputs */ State32 state = new State32(); ResetState32(state, seed); UpdateState32(state, input, offset, length); return(DigestState32(state)); #else InputTextStream p = new InputTextStream(input, offset); long bEnd = p.Position + length; uint h32; if (length >= 16) { long limit = bEnd - 16; uint v1 = seed + PRIME32_1 + PRIME32_2; uint v2 = seed + PRIME32_2; uint v3 = seed + 0; uint v4 = seed - PRIME32_1; do { v1 += p.ReadUInt32() * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; v2 += p.ReadUInt32() * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; v3 += p.ReadUInt32() * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; v4 += p.ReadUInt32() * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; }while (p.Position <= limit); h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); } else { h32 = seed + PRIME32_5; } h32 += (uint)length; while (p.Position + 4 <= bEnd) { h32 += p.ReadUInt32() * PRIME32_3; h32 = XXH_rotl32(h32, 17) * PRIME32_4; } while (p.Position < bEnd) { h32 += p.ReadByte() * PRIME32_5; h32 = XXH_rotl32(h32, 11) * PRIME32_1; } h32 ^= h32 >> 15; h32 *= PRIME32_2; h32 ^= h32 >> 13; h32 *= PRIME32_3; h32 ^= h32 >> 16; return(h32); #endif }
public static ulong XXH64(byte[] input, int offset, int length, ulong seed) { if (input == null) { throw new ArgumentNullException(nameof(input)); } if (input.Rank != 1) { ThrowArrayMultiRank("input"); } if (input.GetLowerBound(0) != 0) { ThrowArrayNonZeroLowerBound("input"); } if (offset < 0) { ThrowArgumentNonNegativeNumber("offset"); } if (length < 0) { ThrowArgumentNonNegativeNumber("length"); } if (input.Length < (offset + length)) { ThrowArrayInvalidOffsetAndLength(); } var p = new InputTextStream(input, offset); long bEnd = p.Position + length; ulong h64; if (length >= 32) { var limit = bEnd - 32; var v1 = seed + PRIME64_1 + PRIME64_2; var v2 = seed + PRIME64_2; var v3 = seed + 0; var v4 = seed - PRIME64_1; do { v1 += p.ReadUInt64() * PRIME64_2; v1 = XXH_rotl64(v1, 31); v1 *= PRIME64_1; v2 += p.ReadUInt64() * PRIME64_2; v2 = XXH_rotl64(v2, 31); v2 *= PRIME64_1; v3 += p.ReadUInt64() * PRIME64_2; v3 = XXH_rotl64(v3, 31); v3 *= PRIME64_1; v4 += p.ReadUInt64() * PRIME64_2; v4 = XXH_rotl64(v4, 31); v4 *= PRIME64_1; } while (p.Position <= limit); h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18); v1 *= PRIME64_2; v1 = XXH_rotl64(v1, 31); v1 *= PRIME64_1; h64 ^= v1; h64 = h64 * PRIME64_1 + PRIME64_4; v2 *= PRIME64_2; v2 = XXH_rotl64(v2, 31); v2 *= PRIME64_1; h64 ^= v2; h64 = h64 * PRIME64_1 + PRIME64_4; v3 *= PRIME64_2; v3 = XXH_rotl64(v3, 31); v3 *= PRIME64_1; h64 ^= v3; h64 = h64 * PRIME64_1 + PRIME64_4; v4 *= PRIME64_2; v4 = XXH_rotl64(v4, 31); v4 *= PRIME64_1; h64 ^= v4; h64 = h64 * PRIME64_1 + PRIME64_4; } else { h64 = seed + PRIME64_5; } h64 += (ulong)length; while (p.Position + 8 <= bEnd) { var k1 = p.ReadUInt64(); k1 *= PRIME64_2; k1 = XXH_rotl64(k1, 31); k1 *= PRIME64_1; h64 ^= k1; h64 = XXH_rotl64(h64, 27) * PRIME64_1 + PRIME64_4; } if (p.Position + 4 <= bEnd) { h64 ^= (ulong)(p.ReadUInt32()) * PRIME64_1; h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3; } while (p.Position < bEnd) { h64 ^= p.ReadByte() * PRIME64_5; h64 = XXH_rotl64(h64, 11) * PRIME64_1; } h64 ^= h64 >> 33; h64 *= PRIME64_2; h64 ^= h64 >> 29; h64 *= PRIME64_3; h64 ^= h64 >> 32; return(h64); }
/* * XXH32() : * Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". * The memory between offset & offset+length in "input" must be valid (allocated and read-accessible). * "seed" can be used to alter the result predictably. * * Original C implementation definition: * unsigned int XXH32 (const void* input, size_t length, unsigned seed); * * XXH64() : * Calculate the 64-bits hash of sequence "length" bytes stored at memory address "input". * Faster on 64-bits systems. Slower on 32-bits systems. * * Original C implementation definition: * unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed); */ public static uint XXH32(byte[] input, int offset, int length, uint seed) { if (input == null) { throw new ArgumentNullException(nameof(input)); } if (input.Rank != 1) { ThrowArrayMultiRank("input"); } if (input.GetLowerBound(0) != 0) { ThrowArrayNonZeroLowerBound("input"); } if (offset < 0) { ThrowArgumentNonNegativeNumber("offset"); } if (length < 0) { ThrowArgumentNonNegativeNumber("length"); } if (input.Length < (offset + length)) { ThrowArrayInvalidOffsetAndLength(); } var p = new InputTextStream(input, offset); long bEnd = p.Position + length; uint h32; if (length >= 16) { var limit = bEnd - 16; var v1 = seed + PRIME32_1 + PRIME32_2; var v2 = seed + PRIME32_2; var v3 = seed + 0; var v4 = seed - PRIME32_1; do { v1 += p.ReadUInt32() * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; v2 += p.ReadUInt32() * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; v3 += p.ReadUInt32() * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; v4 += p.ReadUInt32() * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; } while (p.Position <= limit); h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); } else { h32 = seed + PRIME32_5; } h32 += (uint)length; while (p.Position + 4 <= bEnd) { h32 += p.ReadUInt32() * PRIME32_3; h32 = XXH_rotl32(h32, 17) * PRIME32_4; } while (p.Position < bEnd) { h32 += p.ReadByte() * PRIME32_5; h32 = XXH_rotl32(h32, 11) * PRIME32_1; } h32 ^= h32 >> 15; h32 *= PRIME32_2; h32 ^= h32 >> 13; h32 *= PRIME32_3; h32 ^= h32 >> 16; return(h32); }