XXHash
#include <Windows.h>
#define XXH64_PRIME1 0x9E3779B185EBCA87ULL
#define XXH64_PRIME2 0xC2B2AE3D27D4EB4FULL
#define XXH64_PRIME3 0x165667B19E3779F9ULL
#define XXH64_PRIME4 0x85EBCA77C2B2AE63ULL
#define XXH64_PRIME5 0x27D4EB2F165667C5ULL
SIZE_T StringLengthW(_In_ LPCWSTR String)
{
LPCWSTR String2;
for (String2 = String; *String2; ++String2);
return (String2 - String);
}
UINT64 RotateToLeft64(UINT64 x, UINT64 Rotate)
{
return (x << Rotate) | (x >> (64 - Rotate));
}
UINT64 Read8BytesFrom64ByteValue(PVOID Pointer)
{
return *(PUINT64)Pointer;
}
UINT64 XXHash64String(PVOID Input, SIZE_T Length, UINT64 Seed)
{
PBYTE Pointer = (PBYTE)Input;
PBYTE InputEnd = Pointer + Length;
UINT64 Hash;
if (Length >= 32)
{
PUINT8 Limit = InputEnd - 32;
UINT64 Offset8Bytes1 = Seed + XXH64_PRIME1 + XXH64_PRIME2;
UINT64 Offset8Bytes2 = Seed + XXH64_PRIME2;
UINT64 Offset8Bytes3 = Seed + 0;
UINT64 Offset8Bytes4 = Seed - XXH64_PRIME1;
do {
Offset8Bytes1 = RotateToLeft64(Offset8Bytes1 + Read8BytesFrom64ByteValue(Pointer) * XXH64_PRIME2, 31) * XXH64_PRIME1;
Pointer += 8;
Offset8Bytes2 = RotateToLeft64(Offset8Bytes2 + Read8BytesFrom64ByteValue(Pointer) * XXH64_PRIME2, 31) * XXH64_PRIME1;
Pointer += 8;
Offset8Bytes3 = RotateToLeft64(Offset8Bytes3 + Read8BytesFrom64ByteValue(Pointer) * XXH64_PRIME2, 31) * XXH64_PRIME1;
Pointer += 8;
Offset8Bytes4 = RotateToLeft64(Offset8Bytes4 + Read8BytesFrom64ByteValue(Pointer) * XXH64_PRIME2, 31) * XXH64_PRIME1;
Pointer += 8;
} while (Pointer <= Limit);
Hash = RotateToLeft64(Offset8Bytes1, 1);
Hash += RotateToLeft64(Offset8Bytes2, 7);
Hash += RotateToLeft64(Offset8Bytes3, 12);
Hash += RotateToLeft64(Offset8Bytes4, 18);
Offset8Bytes1 = RotateToLeft64(Offset8Bytes1 * XXH64_PRIME2, 31) * XXH64_PRIME1;
Offset8Bytes2 = RotateToLeft64(Offset8Bytes2 * XXH64_PRIME2, 31) * XXH64_PRIME1;
Offset8Bytes3 = RotateToLeft64(Offset8Bytes3 * XXH64_PRIME2, 31) * XXH64_PRIME1;
Offset8Bytes4 = RotateToLeft64(Offset8Bytes4 * XXH64_PRIME2, 31) * XXH64_PRIME1;
Hash ^= Offset8Bytes1;
Hash = Hash * XXH64_PRIME1 + XXH64_PRIME4;
Hash ^= Offset8Bytes2;
Hash = Hash * XXH64_PRIME1 + XXH64_PRIME4;
Hash ^= Offset8Bytes3;
Hash = Hash * XXH64_PRIME1 + XXH64_PRIME4;
Hash ^= Offset8Bytes4;
Hash = Hash * XXH64_PRIME1 + XXH64_PRIME4;
}
else
Hash = Seed + XXH64_PRIME5;
Hash += Length;
while (Pointer + 8 <= InputEnd)
{
Hash ^= RotateToLeft64(Read8BytesFrom64ByteValue(Pointer) * XXH64_PRIME2, 31) * XXH64_PRIME1;
Hash = RotateToLeft64(Hash, 27) * XXH64_PRIME1 + XXH64_PRIME4;
Pointer += 8;
}
if (Pointer + 4 <= InputEnd)
{
Hash ^= (UINT64)(*(PUINT32)Pointer) * XXH64_PRIME1;
Hash = RotateToLeft64(Hash, 23) * XXH64_PRIME2 + XXH64_PRIME3;
Pointer += 4;
}
while (Pointer < InputEnd)
{
Hash ^= (*Pointer++) * XXH64_PRIME5;
Hash = RotateToLeft64(Hash, 11) * XXH64_PRIME1;
}
Hash ^= Hash >> 33;
Hash *= XXH64_PRIME2;
Hash ^= Hash >> 29;
Hash *= XXH64_PRIME3;
Hash ^= Hash >> 32;
return Hash;
}
INT main(VOID)
{
WCHAR StringHashExample[] = L"Hash This String";
ULONGLONG Hash = 0;
Hash = XXHash64String(StringHashExample, (StringLengthW(StringHashExample) * sizeof(WCHAR)), 100); //100 should be seed, random number
return ERROR_SUCCESS;
}Last updated