Murmur3

#include <Windows.h>

PVOID CopyMemoryEx(_Inout_ PVOID Destination, _In_ CONST PVOID Source, _In_ SIZE_T Length)
{
    PBYTE D = (PBYTE)Destination;
    PBYTE S = (PBYTE)Source;

    while (Length--)
        *D++ = *S++;

    return Destination;
}

SIZE_T StringLengthW(_In_ LPCWSTR String)
{
    LPCWSTR String2;

    for (String2 = String; *String2; ++String2);

    return (String2 - String);
}


UINT32 RotateToLeft32(UINT64 x, UINT64 Rotate)
{
    return (x << Rotate) | (x >> (32 - Rotate));
}

UINT32 HashStringMurmur3(PVOID String, SIZE_T Length, UINT32 Seed)
{
    PBYTE Pointer = (PBYTE)String;
    PBYTE InputEnd = Pointer + (Length & ~(SIZE_T)3);
    UINT32 Magic1 = 0xcc9e2d51;
    UINT32 Magic2 = 0x1b873593;
    UINT32 ChunkMagic = 0;
    UINT32 Hash = Seed;

    while (Pointer < InputEnd)
    {
        UINT32 Chunk = 0;

        CopyMemoryEx(&Chunk, Pointer, 4);

        Chunk *= Magic1;
        Chunk = RotateToLeft32(Chunk, 15);
        Chunk *= Magic2;

        Hash ^= Chunk;
        Hash = RotateToLeft32(Hash, 13);
        Hash = Hash * 5 + 0xe6546b64;

        Pointer += 4;
    }

    switch (Length & 3) 
    {
        case 3: ChunkMagic ^= Pointer[2] << 16;
        case 2: ChunkMagic ^= Pointer[1] << 8;
        case 1:
            ChunkMagic ^= Pointer[0];
            ChunkMagic *= Magic1;
            ChunkMagic = RotateToLeft32(ChunkMagic, 15);
            ChunkMagic *= Magic2;
            Hash ^= ChunkMagic;
    }

    Hash ^= Length;
    Hash ^= Hash >> 16;
    Hash *= 0x85ebca6b;
    Hash ^= Hash >> 13;
    Hash *= 0xc2b2ae35;
    Hash ^= Hash >> 16;

    return Hash;

}

INT main(VOID)
{
    WCHAR StringHashExample[] = L"Hash This String";
    UINT32 Hash = 0;

    Hash = HashStringMurmur3(StringHashExample, (StringLengthW(StringHashExample) * sizeof(WCHAR)), 1);

    return ERROR_SUCCESS;
}

Last updated