Skip to content

Instantly share code, notes, and snippets.

@kajuberdut
Created November 27, 2021 17:48
Show Gist options
  • Save kajuberdut/9962fac4f7f119026d934fbdbd474016 to your computer and use it in GitHub Desktop.
Save kajuberdut/9962fac4f7f119026d934fbdbd474016 to your computer and use it in GitHub Desktop.
Pure python murmer3 32 bit
CONST_START = 0x0
CONST1 = 0xCC9E2D51
CONST2 = 0x1B873593
def hash_word(text: str):
"""
32bit murmur3 hash.
Written by Patrick Shechet
Based on pymmh3 by Fredrik Kihlander and Swapnil Gusani: https://github.com/wc-duck/pymmh3/blob/master/pymmh3.py
"""
key = bytearray(text.encode())
length = len(key)
nblocks = int(length / 4)
h1 = CONST_START
# for each fourByteChunk of key
for four_byte_chunk in range(0, nblocks * 4, 4):
k1 = (
key[four_byte_chunk + 3] << 24
| key[four_byte_chunk + 2] << 16
| key[four_byte_chunk + 1] << 8
| key[four_byte_chunk + 0]
)
k1 = (CONST1 * k1) & 0xFFFFFFFF
k1 = (k1 << 15 | k1 >> 17) & 0xFFFFFFFF
k1 = (CONST2 * k1) & 0xFFFFFFFF
h1 ^= k1
h1 = (h1 << 13 | h1 >> 19) & 0xFFFFFFFF
h1 = (h1 * 5 + 0xE6546B64) & 0xFFFFFFFF
tail_index = nblocks * 4
k1 = 0
tail_size = length & 3
if tail_size >= 3:
k1 ^= key[tail_index + 2] << 16
if tail_size >= 2:
k1 ^= key[tail_index + 1] << 8
if tail_size >= 1:
k1 ^= key[tail_index + 0]
if tail_size > 0:
k1 = (k1 * CONST1) & 0xFFFFFFFF
k1 = (k1 << 15 | k1 >> 17) & 0xFFFFFFFF
k1 = (k1 * CONST2) & 0xFFFFFFFF
h1 ^= k1
unsigned_val = h1 ^ length
unsigned_val ^= unsigned_val >> 16
unsigned_val = (unsigned_val * 0x85EBCA6B) & 0xFFFFFFFF
unsigned_val ^= unsigned_val >> 13
unsigned_val = (unsigned_val * 0xC2B2AE35) & 0xFFFFFFFF
unsigned_val ^= unsigned_val >> 16
if unsigned_val & 0x80000000 == 0:
return unsigned_val
else:
return -((unsigned_val ^ 0xFFFFFFFF) + 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment