Module refinery.lib.murmur
Murmur hash implementation, orignally written by Fredrik Kihlander and enhanced by Swapnil Gusani. See also their original source code.
Expand source code Browse git
"""
Murmur hash implementation, orignally written by Fredrik Kihlander and enhanced by Swapnil Gusani.
See also their [original source code](https://github.com/wc-duck/pymmh3).
"""
from __future__ import annotations
from refinery.lib import chunks
from refinery.lib.types import Binary
from itertools import zip_longest
from struct import unpack
def mmh32(key: Binary, seed=0) -> int:
key = memoryview(key)
def fmix(h: int) -> int:
h ^= h >> 16
h *= 0x85EBCA6B
h &= 0xFFFFFFFF
h ^= h >> 13
h *= 0xC2B2AE35
h &= 0xFFFFFFFF
h ^= h >> 16
return h
length = len(key)
tail_size = length & 3
tail_index = length - tail_size
h1 = seed
c1 = 0xCC9E2D51
c2 = 0x1B873593
for block_start in range(0, tail_index, 4):
k1 = int.from_bytes(key[block_start:block_start + 4], 'little', signed=False)
k1 = (c1 * k1) & 0xFFFFFFFF
k1 = (k1 << 15 | k1 >> 17) & 0xFFFFFFFF
k1 = (c2 * k1) & 0xFFFFFFFF
h1 ^= k1
h1 = (h1 << 13 | h1 >> 19) & 0xFFFFFFFF
h1 = (h1 * 5 + 0xE6546B64) & 0xFFFFFFFF
k1 = 0
if tail_size >= 3:
k1 ^= key[tail_index + 2] << 0x10
if tail_size >= 2:
k1 ^= key[tail_index + 1] << 0x08
if tail_size >= 1:
k1 ^= key[tail_index + 0]
if tail_size > 0:
k1 = (k1 * c1) & 0xFFFFFFFF
k1 = (k1 << 15 | k1 >> 17) & 0xFFFFFFFF
k1 = (k1 * c2) & 0xFFFFFFFF
h1 ^= k1
return fmix(h1 ^ length)
def v3_mmh32digest(key: Binary, seed: int = 0) -> bytes:
return mmh32(key, seed).to_bytes(4, 'big')
def mmh128x64(key: Binary, seed: int = 0) -> int:
key = memoryview(key)
def fmix(k):
k ^= k >> 33
k *= 0xFF51AFD7ED558CCD
k &= 0xFFFFFFFFFFFFFFFF
k ^= k >> 33
k *= 0xC4CEB9FE1A85EC53
k &= 0xFFFFFFFFFFFFFFFF
k ^= k >> 33
return k
length = len(key)
tail_size = length & 15
tail_index = length - tail_size
h1: int = seed
h2: int = seed
c1 = 0x87C37B91114253D5
c2 = 0x4CF5AD432745937F
for block_start in range(0, tail_index, 16):
k1, k2 = unpack('<QQ', key[block_start:block_start + 16])
k1 = (c1 * k1) & 0xFFFFFFFFFFFFFFFF
k1 = (k1 << 31 | k1 >> 33) & 0xFFFFFFFFFFFFFFFF
k1 = (c2 * k1) & 0xFFFFFFFFFFFFFFFF
h1 ^= k1
h1 = (h1 << 27 | h1 >> 37) & 0xFFFFFFFFFFFFFFFF
h1 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF
h1 = (h1 * 5 + 0x52DCE729) & 0xFFFFFFFFFFFFFFFF
k2 = (c2 * k2) & 0xFFFFFFFFFFFFFFFF
k2 = (k2 << 33 | k2 >> 31) & 0xFFFFFFFFFFFFFFFF
k2 = (c1 * k2) & 0xFFFFFFFFFFFFFFFF
h2 ^= k2
h2 = (h2 << 31 | h2 >> 33) & 0xFFFFFFFFFFFFFFFF
h2 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF
h2 = (h2 * 5 + 0x38495AB5) & 0xFFFFFFFFFFFFFFFF
k1 = 0
k2 = 0
if tail_size >= 0xF:
k2 ^= key[tail_index + 0xE] << 0x30
if tail_size >= 0xE:
k2 ^= key[tail_index + 0xD] << 0x28
if tail_size >= 0xD:
k2 ^= key[tail_index + 0xC] << 0x20
if tail_size >= 0xC:
k2 ^= key[tail_index + 0xB] << 0x18
if tail_size >= 0xB:
k2 ^= key[tail_index + 0xA] << 0x10
if tail_size >= 0xA:
k2 ^= key[tail_index + 0x9] << 0x08
if tail_size >= 0x9:
k2 ^= key[tail_index + 0x8]
if tail_size > 8:
k2 = (k2 * c2) & 0xFFFFFFFFFFFFFFFF
k2 = (k2 << 33 | k2 >> 31) & 0xFFFFFFFFFFFFFFFF
k2 = (k2 * c1) & 0xFFFFFFFFFFFFFFFF
h2 ^= k2
if tail_size >= 8:
k1 ^= key[tail_index + 7] << 0x38
if tail_size >= 7:
k1 ^= key[tail_index + 6] << 0x30
if tail_size >= 6:
k1 ^= key[tail_index + 5] << 0x28
if tail_size >= 5:
k1 ^= key[tail_index + 4] << 0x20
if tail_size >= 4:
k1 ^= key[tail_index + 3] << 0x18
if tail_size >= 3:
k1 ^= key[tail_index + 2] << 0x10
if tail_size >= 2:
k1 ^= key[tail_index + 1] << 0x08
if tail_size >= 1:
k1 ^= key[tail_index + 0]
if tail_size > 0:
k1 = (k1 * c1) & 0xFFFFFFFFFFFFFFFF
k1 = (k1 << 31 | k1 >> 33) & 0xFFFFFFFFFFFFFFFF
k1 = (k1 * c2) & 0xFFFFFFFFFFFFFFFF
h1 ^= k1
h1 ^= length
h2 ^= length
h1 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF
h2 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF
h1 = fmix(h1)
h2 = fmix(h2)
h1 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF
h2 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF
return (h1 << 64 | h2)
def mmh128x32(key: Binary, seed: int = 0) -> int:
key = memoryview(key)
def fmix(h: int) -> int:
h ^= h >> 16
h *= 0x85EBCA6B
h &= 0xFFFFFFFF
h ^= h >> 13
h *= 0xC2B2AE35
h &= 0xFFFFFFFF
h ^= h >> 16
return h
length = len(key)
tail_size = length & 15
tail_index = length - tail_size
h1, h2, h3, h4 = seed, seed, seed, seed
c1 = 0x239B961B
c2 = 0xAB0E9789
c3 = 0x38B34AE5
c4 = 0xA1E38B93
for block_start in range(0, tail_index, 16):
k1, k2, k3, k4 = unpack('<LLLL', key[block_start:block_start + 16])
k1 = (c1 * k1) & 0xFFFFFFFF
k1 = (k1 << 15 | k1 >> 17) & 0xFFFFFFFF
k1 = (c2 * k1) & 0xFFFFFFFF
h1 ^= k1
h1 = (h1 << 19 | h1 >> 13) & 0xFFFFFFFF
h1 = (h1 + h2) & 0xFFFFFFFF
h1 = (h1 * 5 + 0x561ccd1b) & 0xFFFFFFFF
k2 = (c2 * k2) & 0xFFFFFFFF
k2 = (k2 << 16 | k2 >> 16) & 0xFFFFFFFF
k2 = (c3 * k2) & 0xFFFFFFFF
h2 ^= k2
h2 = (h2 << 17 | h2 >> 15) & 0xFFFFFFFF
h2 = (h2 + h3) & 0xFFFFFFFF
h2 = (h2 * 5 + 0x0bcaa747) & 0xFFFFFFFF
k3 = (c3 * k3) & 0xFFFFFFFF
k3 = (k3 << 17 | k3 >> 15) & 0xFFFFFFFF
k3 = (c4 * k3) & 0xFFFFFFFF
h3 ^= k3
h3 = (h3 << 15 | h3 >> 17) & 0xFFFFFFFF
h3 = (h3 + h4) & 0xFFFFFFFF
h3 = (h3 * 5 + 0x96cd1c35) & 0xFFFFFFFF
k4 = (c4 * k4) & 0xFFFFFFFF
k4 = (k4 << 18 | k4 >> 14) & 0xFFFFFFFF
k4 = (c1 * k4) & 0xFFFFFFFF
h4 ^= k4
h4 = (h4 << 13 | h4 >> 19) & 0xFFFFFFFF
h4 = (h1 + h4) & 0xFFFFFFFF
h4 = (h4 * 5 + 0x32ac3b17) & 0xFFFFFFFF
k1 = 0
k2 = 0
k3 = 0
k4 = 0
if tail_size >= 0xF:
k4 ^= key[tail_index + 0xE] << 0x10
if tail_size >= 0xE:
k4 ^= key[tail_index + 0xD] << 0x08
if tail_size >= 0xD:
k4 ^= key[tail_index + 0xC]
if tail_size > 12:
k4 = (k4 * c4) & 0xFFFFFFFF
k4 = (k4 << 18 | k4 >> 14) & 0xFFFFFFFF
k4 = (k4 * c1) & 0xFFFFFFFF
h4 ^= k4
if tail_size >= 0xC:
k3 ^= key[tail_index + 0xB] << 0x18
if tail_size >= 0xB:
k3 ^= key[tail_index + 0xA] << 0x10
if tail_size >= 0xA:
k3 ^= key[tail_index + 0x9] << 0x08
if tail_size >= 0x9:
k3 ^= key[tail_index + 0x8]
if tail_size > 8:
k3 = (k3 * c3) & 0xFFFFFFFF
k3 = (k3 << 17 | k3 >> 15) & 0xFFFFFFFF
k3 = (k3 * c4) & 0xFFFFFFFF
h3 ^= k3
if tail_size >= 8:
k2 ^= key[tail_index + 7] << 0x18
if tail_size >= 7:
k2 ^= key[tail_index + 6] << 0x10
if tail_size >= 6:
k2 ^= key[tail_index + 5] << 0x08
if tail_size >= 5:
k2 ^= key[tail_index + 4]
if tail_size > 4:
k2 = (k2 * c2) & 0xFFFFFFFF
k2 = (k2 << 16 | k2 >> 16) & 0xFFFFFFFF
k2 = (k2 * c3) & 0xFFFFFFFF
h2 ^= k2
if tail_size >= 4:
k1 ^= key[tail_index + 3] << 0x18
if tail_size >= 3:
k1 ^= key[tail_index + 2] << 0x10
if tail_size >= 2:
k1 ^= key[tail_index + 1] << 0x08
if tail_size >= 1:
k1 ^= key[tail_index + 0]
if tail_size > 0:
k1 = (k1 * c1) & 0xFFFFFFFF
k1 = (k1 << 15 | k1 >> 17) & 0xFFFFFFFF
k1 = (k1 * c2) & 0xFFFFFFFF
h1 ^= k1
h1 ^= length
h2 ^= length
h3 ^= length
h4 ^= length
h1 = (h1 + h2) & 0xFFFFFFFF
h1 = (h1 + h3) & 0xFFFFFFFF
h1 = (h1 + h4) & 0xFFFFFFFF
h2 = (h1 + h2) & 0xFFFFFFFF
h3 = (h1 + h3) & 0xFFFFFFFF
h4 = (h1 + h4) & 0xFFFFFFFF
h1 = fmix(h1)
h2 = fmix(h2)
h3 = fmix(h3)
h4 = fmix(h4)
h1 = (h1 + h2) & 0xFFFFFFFF
h1 = (h1 + h3) & 0xFFFFFFFF
h1 = (h1 + h4) & 0xFFFFFFFF
h2 = (h1 + h2) & 0xFFFFFFFF
h3 = (h1 + h3) & 0xFFFFFFFF
h4 = (h1 + h4) & 0xFFFFFFFF
return (h1 << 96 | h2 << 64 | h3 << 32 | h4)
def v3_mmh128digest64(key: Binary, seed: int = 0) -> bytes:
return mmh128x64(key, seed).to_bytes(0x10, 'big')
def v3_mmh128digest32(key: Binary, seed: int = 0) -> bytes:
return mmh128x32(key, seed).to_bytes(0x10, 'big')
# Begin MurmurHash v2 Implementation
def v2_mmh32digest(data: Binary, seed: int):
seed ^= len(data)
j = len(data) % 4
e = len(data) - j
view = memoryview(data)
body = view[:e]
tail = view[e:]
h = seed & 0xFFFFFFFF
for k in chunks.unpack(body, 4):
k *= 0x5BD1E995
k &= 0xFFFFFFFF
k ^= k >> 24
k *= 0x5BD1E995
k &= 0xFFFFFFFF
h *= 0x5BD1E995
h &= 0xFFFFFFFF
h ^= k
while j > 0:
j -= 1
h ^= tail[j] << (j << 3)
if tail:
h *= 0x5BD1E995
h &= 0xFFFFFFFF
h ^= h >> 13
h *= 0x5BD1E995
h &= 0xFFFFFFFF
h ^= h >> 15
return h.to_bytes(4, 'big')
def v2_mmh64digestA(data: Binary, seed: int):
seed ^= len(data) * 0xC6A4A7935BD1E995
j = len(data) % 8
e = len(data) - j
view = memoryview(data)
body = view[:e]
tail = view[e:]
mask = 0xFFFFFFFFFFFFFFFF
h = seed & mask
for k in chunks.unpack(body, 8):
k *= 0xC6A4A7935BD1E995
k &= 0xFFFFFFFFFFFFFFFF
k ^= k >> 47
k *= 0xC6A4A7935BD1E995
k &= 0xFFFFFFFFFFFFFFFF
h ^= k
h *= 0xC6A4A7935BD1E995
h &= 0xFFFFFFFFFFFFFFFF
while j > 0:
j -= 1
h ^= tail[j] << (j << 3)
if tail:
h *= 0xC6A4A7935BD1E995
h &= 0xFFFFFFFFFFFFFFFF
h ^= h >> 47
h *= 0xC6A4A7935BD1E995
h &= 0xFFFFFFFFFFFFFFFF
h ^= h >> 47
return h.to_bytes(8, 'big')
def v2_mmh64digestB(data: Binary, seed: int):
h1 = seed ^ len(data)
h2 = seed >> 32
h1 &= 0xFFFFFFFF
h2 &= 0xFFFFFFFF
view = memoryview(data)
j = len(data) % 4
m = len(data) - j
body = view[:m]
tail = view[m:]
it = iter(chunks.unpack(body, 4))
for k1, k2 in zip_longest(it, it):
k1 *= 0x5BD1E995
k1 &= 0xFFFFFFFF
k1 ^= k1 >> 24
k1 *= 0x5BD1E995
k1 &= 0xFFFFFFFF
h1 *= 0x5BD1E995
h1 &= 0xFFFFFFFF
h1 ^= k1
if k2 is None:
break
k2 *= 0x5BD1E995
k2 &= 0xFFFFFFFF
k2 ^= k2 >> 24
k2 *= 0x5BD1E995
k2 &= 0xFFFFFFFF
h2 *= 0x5BD1E995
h2 &= 0xFFFFFFFF
h2 ^= k2
while j > 0:
j -= 1
h2 ^= tail[j] << (j << 3)
if tail:
h2 *= 0x5BD1E995
h2 &= 0xFFFFFFFF
h1 ^= h2 >> 18
h1 *= 0x5BD1E995
h1 &= 0xFFFFFFFF
h2 ^= h1 >> 22
h2 *= 0x5BD1E995
h2 &= 0xFFFFFFFF
h1 ^= h2 >> 17
h1 *= 0x5BD1E995
h1 &= 0xFFFFFFFF
h2 ^= h1 >> 19
h2 *= 0x5BD1E995
h2 &= 0xFFFFFFFF
h = (h1 << 32) | h2
return h.to_bytes(8, 'big')
def v2_mmh32digestA_mmix(h, k):
k *= 0x5BD1E995
k &= 0xFFFFFFFF
k ^= k >> 24
k *= 0x5BD1E995
k &= 0xFFFFFFFF
h *= 0x5BD1E995
h &= 0xFFFFFFFF
h ^= k
return (h, k)
def v2_mmh32digestA(data: Binary, seed: int):
n = len(data)
h = seed & 0xFFFFFFFF
j = len(data) % 4
e = len(data) - j
t = 0
view = memoryview(data)
body = view[:e]
tail = view[e:]
for k in chunks.unpack(body, 4):
h, k = v2_mmh32digestA_mmix(h, k)
while j > 0:
j -= 1
t ^= tail[j] << (j << 3)
h, t = v2_mmh32digestA_mmix(h, t)
h, n = v2_mmh32digestA_mmix(h, n)
h ^= h >> 13
h *= 0x5BD1E995
h &= 0xFFFFFFFF
h ^= h >> 15
return h.to_bytes(4, 'big')
Functions
def mmh32(key, seed=0)
-
Expand source code Browse git
def mmh32(key: Binary, seed=0) -> int: key = memoryview(key) def fmix(h: int) -> int: h ^= h >> 16 h *= 0x85EBCA6B h &= 0xFFFFFFFF h ^= h >> 13 h *= 0xC2B2AE35 h &= 0xFFFFFFFF h ^= h >> 16 return h length = len(key) tail_size = length & 3 tail_index = length - tail_size h1 = seed c1 = 0xCC9E2D51 c2 = 0x1B873593 for block_start in range(0, tail_index, 4): k1 = int.from_bytes(key[block_start:block_start + 4], 'little', signed=False) k1 = (c1 * k1) & 0xFFFFFFFF k1 = (k1 << 15 | k1 >> 17) & 0xFFFFFFFF k1 = (c2 * k1) & 0xFFFFFFFF h1 ^= k1 h1 = (h1 << 13 | h1 >> 19) & 0xFFFFFFFF h1 = (h1 * 5 + 0xE6546B64) & 0xFFFFFFFF k1 = 0 if tail_size >= 3: k1 ^= key[tail_index + 2] << 0x10 if tail_size >= 2: k1 ^= key[tail_index + 1] << 0x08 if tail_size >= 1: k1 ^= key[tail_index + 0] if tail_size > 0: k1 = (k1 * c1) & 0xFFFFFFFF k1 = (k1 << 15 | k1 >> 17) & 0xFFFFFFFF k1 = (k1 * c2) & 0xFFFFFFFF h1 ^= k1 return fmix(h1 ^ length)
def v3_mmh32digest(key, seed=0)
-
Expand source code Browse git
def v3_mmh32digest(key: Binary, seed: int = 0) -> bytes: return mmh32(key, seed).to_bytes(4, 'big')
def mmh128x64(key, seed=0)
-
Expand source code Browse git
def mmh128x64(key: Binary, seed: int = 0) -> int: key = memoryview(key) def fmix(k): k ^= k >> 33 k *= 0xFF51AFD7ED558CCD k &= 0xFFFFFFFFFFFFFFFF k ^= k >> 33 k *= 0xC4CEB9FE1A85EC53 k &= 0xFFFFFFFFFFFFFFFF k ^= k >> 33 return k length = len(key) tail_size = length & 15 tail_index = length - tail_size h1: int = seed h2: int = seed c1 = 0x87C37B91114253D5 c2 = 0x4CF5AD432745937F for block_start in range(0, tail_index, 16): k1, k2 = unpack('<QQ', key[block_start:block_start + 16]) k1 = (c1 * k1) & 0xFFFFFFFFFFFFFFFF k1 = (k1 << 31 | k1 >> 33) & 0xFFFFFFFFFFFFFFFF k1 = (c2 * k1) & 0xFFFFFFFFFFFFFFFF h1 ^= k1 h1 = (h1 << 27 | h1 >> 37) & 0xFFFFFFFFFFFFFFFF h1 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF h1 = (h1 * 5 + 0x52DCE729) & 0xFFFFFFFFFFFFFFFF k2 = (c2 * k2) & 0xFFFFFFFFFFFFFFFF k2 = (k2 << 33 | k2 >> 31) & 0xFFFFFFFFFFFFFFFF k2 = (c1 * k2) & 0xFFFFFFFFFFFFFFFF h2 ^= k2 h2 = (h2 << 31 | h2 >> 33) & 0xFFFFFFFFFFFFFFFF h2 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF h2 = (h2 * 5 + 0x38495AB5) & 0xFFFFFFFFFFFFFFFF k1 = 0 k2 = 0 if tail_size >= 0xF: k2 ^= key[tail_index + 0xE] << 0x30 if tail_size >= 0xE: k2 ^= key[tail_index + 0xD] << 0x28 if tail_size >= 0xD: k2 ^= key[tail_index + 0xC] << 0x20 if tail_size >= 0xC: k2 ^= key[tail_index + 0xB] << 0x18 if tail_size >= 0xB: k2 ^= key[tail_index + 0xA] << 0x10 if tail_size >= 0xA: k2 ^= key[tail_index + 0x9] << 0x08 if tail_size >= 0x9: k2 ^= key[tail_index + 0x8] if tail_size > 8: k2 = (k2 * c2) & 0xFFFFFFFFFFFFFFFF k2 = (k2 << 33 | k2 >> 31) & 0xFFFFFFFFFFFFFFFF k2 = (k2 * c1) & 0xFFFFFFFFFFFFFFFF h2 ^= k2 if tail_size >= 8: k1 ^= key[tail_index + 7] << 0x38 if tail_size >= 7: k1 ^= key[tail_index + 6] << 0x30 if tail_size >= 6: k1 ^= key[tail_index + 5] << 0x28 if tail_size >= 5: k1 ^= key[tail_index + 4] << 0x20 if tail_size >= 4: k1 ^= key[tail_index + 3] << 0x18 if tail_size >= 3: k1 ^= key[tail_index + 2] << 0x10 if tail_size >= 2: k1 ^= key[tail_index + 1] << 0x08 if tail_size >= 1: k1 ^= key[tail_index + 0] if tail_size > 0: k1 = (k1 * c1) & 0xFFFFFFFFFFFFFFFF k1 = (k1 << 31 | k1 >> 33) & 0xFFFFFFFFFFFFFFFF k1 = (k1 * c2) & 0xFFFFFFFFFFFFFFFF h1 ^= k1 h1 ^= length h2 ^= length h1 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF h2 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF h1 = fmix(h1) h2 = fmix(h2) h1 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF h2 = (h1 + h2) & 0xFFFFFFFFFFFFFFFF return (h1 << 64 | h2)
def mmh128x32(key, seed=0)
-
Expand source code Browse git
def mmh128x32(key: Binary, seed: int = 0) -> int: key = memoryview(key) def fmix(h: int) -> int: h ^= h >> 16 h *= 0x85EBCA6B h &= 0xFFFFFFFF h ^= h >> 13 h *= 0xC2B2AE35 h &= 0xFFFFFFFF h ^= h >> 16 return h length = len(key) tail_size = length & 15 tail_index = length - tail_size h1, h2, h3, h4 = seed, seed, seed, seed c1 = 0x239B961B c2 = 0xAB0E9789 c3 = 0x38B34AE5 c4 = 0xA1E38B93 for block_start in range(0, tail_index, 16): k1, k2, k3, k4 = unpack('<LLLL', key[block_start:block_start + 16]) k1 = (c1 * k1) & 0xFFFFFFFF k1 = (k1 << 15 | k1 >> 17) & 0xFFFFFFFF k1 = (c2 * k1) & 0xFFFFFFFF h1 ^= k1 h1 = (h1 << 19 | h1 >> 13) & 0xFFFFFFFF h1 = (h1 + h2) & 0xFFFFFFFF h1 = (h1 * 5 + 0x561ccd1b) & 0xFFFFFFFF k2 = (c2 * k2) & 0xFFFFFFFF k2 = (k2 << 16 | k2 >> 16) & 0xFFFFFFFF k2 = (c3 * k2) & 0xFFFFFFFF h2 ^= k2 h2 = (h2 << 17 | h2 >> 15) & 0xFFFFFFFF h2 = (h2 + h3) & 0xFFFFFFFF h2 = (h2 * 5 + 0x0bcaa747) & 0xFFFFFFFF k3 = (c3 * k3) & 0xFFFFFFFF k3 = (k3 << 17 | k3 >> 15) & 0xFFFFFFFF k3 = (c4 * k3) & 0xFFFFFFFF h3 ^= k3 h3 = (h3 << 15 | h3 >> 17) & 0xFFFFFFFF h3 = (h3 + h4) & 0xFFFFFFFF h3 = (h3 * 5 + 0x96cd1c35) & 0xFFFFFFFF k4 = (c4 * k4) & 0xFFFFFFFF k4 = (k4 << 18 | k4 >> 14) & 0xFFFFFFFF k4 = (c1 * k4) & 0xFFFFFFFF h4 ^= k4 h4 = (h4 << 13 | h4 >> 19) & 0xFFFFFFFF h4 = (h1 + h4) & 0xFFFFFFFF h4 = (h4 * 5 + 0x32ac3b17) & 0xFFFFFFFF k1 = 0 k2 = 0 k3 = 0 k4 = 0 if tail_size >= 0xF: k4 ^= key[tail_index + 0xE] << 0x10 if tail_size >= 0xE: k4 ^= key[tail_index + 0xD] << 0x08 if tail_size >= 0xD: k4 ^= key[tail_index + 0xC] if tail_size > 12: k4 = (k4 * c4) & 0xFFFFFFFF k4 = (k4 << 18 | k4 >> 14) & 0xFFFFFFFF k4 = (k4 * c1) & 0xFFFFFFFF h4 ^= k4 if tail_size >= 0xC: k3 ^= key[tail_index + 0xB] << 0x18 if tail_size >= 0xB: k3 ^= key[tail_index + 0xA] << 0x10 if tail_size >= 0xA: k3 ^= key[tail_index + 0x9] << 0x08 if tail_size >= 0x9: k3 ^= key[tail_index + 0x8] if tail_size > 8: k3 = (k3 * c3) & 0xFFFFFFFF k3 = (k3 << 17 | k3 >> 15) & 0xFFFFFFFF k3 = (k3 * c4) & 0xFFFFFFFF h3 ^= k3 if tail_size >= 8: k2 ^= key[tail_index + 7] << 0x18 if tail_size >= 7: k2 ^= key[tail_index + 6] << 0x10 if tail_size >= 6: k2 ^= key[tail_index + 5] << 0x08 if tail_size >= 5: k2 ^= key[tail_index + 4] if tail_size > 4: k2 = (k2 * c2) & 0xFFFFFFFF k2 = (k2 << 16 | k2 >> 16) & 0xFFFFFFFF k2 = (k2 * c3) & 0xFFFFFFFF h2 ^= k2 if tail_size >= 4: k1 ^= key[tail_index + 3] << 0x18 if tail_size >= 3: k1 ^= key[tail_index + 2] << 0x10 if tail_size >= 2: k1 ^= key[tail_index + 1] << 0x08 if tail_size >= 1: k1 ^= key[tail_index + 0] if tail_size > 0: k1 = (k1 * c1) & 0xFFFFFFFF k1 = (k1 << 15 | k1 >> 17) & 0xFFFFFFFF k1 = (k1 * c2) & 0xFFFFFFFF h1 ^= k1 h1 ^= length h2 ^= length h3 ^= length h4 ^= length h1 = (h1 + h2) & 0xFFFFFFFF h1 = (h1 + h3) & 0xFFFFFFFF h1 = (h1 + h4) & 0xFFFFFFFF h2 = (h1 + h2) & 0xFFFFFFFF h3 = (h1 + h3) & 0xFFFFFFFF h4 = (h1 + h4) & 0xFFFFFFFF h1 = fmix(h1) h2 = fmix(h2) h3 = fmix(h3) h4 = fmix(h4) h1 = (h1 + h2) & 0xFFFFFFFF h1 = (h1 + h3) & 0xFFFFFFFF h1 = (h1 + h4) & 0xFFFFFFFF h2 = (h1 + h2) & 0xFFFFFFFF h3 = (h1 + h3) & 0xFFFFFFFF h4 = (h1 + h4) & 0xFFFFFFFF return (h1 << 96 | h2 << 64 | h3 << 32 | h4)
def v3_mmh128digest64(key, seed=0)
-
Expand source code Browse git
def v3_mmh128digest64(key: Binary, seed: int = 0) -> bytes: return mmh128x64(key, seed).to_bytes(0x10, 'big')
def v3_mmh128digest32(key, seed=0)
-
Expand source code Browse git
def v3_mmh128digest32(key: Binary, seed: int = 0) -> bytes: return mmh128x32(key, seed).to_bytes(0x10, 'big')
def v2_mmh32digest(data, seed)
-
Expand source code Browse git
def v2_mmh32digest(data: Binary, seed: int): seed ^= len(data) j = len(data) % 4 e = len(data) - j view = memoryview(data) body = view[:e] tail = view[e:] h = seed & 0xFFFFFFFF for k in chunks.unpack(body, 4): k *= 0x5BD1E995 k &= 0xFFFFFFFF k ^= k >> 24 k *= 0x5BD1E995 k &= 0xFFFFFFFF h *= 0x5BD1E995 h &= 0xFFFFFFFF h ^= k while j > 0: j -= 1 h ^= tail[j] << (j << 3) if tail: h *= 0x5BD1E995 h &= 0xFFFFFFFF h ^= h >> 13 h *= 0x5BD1E995 h &= 0xFFFFFFFF h ^= h >> 15 return h.to_bytes(4, 'big')
def v2_mmh64digestA(data, seed)
-
Expand source code Browse git
def v2_mmh64digestA(data: Binary, seed: int): seed ^= len(data) * 0xC6A4A7935BD1E995 j = len(data) % 8 e = len(data) - j view = memoryview(data) body = view[:e] tail = view[e:] mask = 0xFFFFFFFFFFFFFFFF h = seed & mask for k in chunks.unpack(body, 8): k *= 0xC6A4A7935BD1E995 k &= 0xFFFFFFFFFFFFFFFF k ^= k >> 47 k *= 0xC6A4A7935BD1E995 k &= 0xFFFFFFFFFFFFFFFF h ^= k h *= 0xC6A4A7935BD1E995 h &= 0xFFFFFFFFFFFFFFFF while j > 0: j -= 1 h ^= tail[j] << (j << 3) if tail: h *= 0xC6A4A7935BD1E995 h &= 0xFFFFFFFFFFFFFFFF h ^= h >> 47 h *= 0xC6A4A7935BD1E995 h &= 0xFFFFFFFFFFFFFFFF h ^= h >> 47 return h.to_bytes(8, 'big')
def v2_mmh64digestB(data, seed)
-
Expand source code Browse git
def v2_mmh64digestB(data: Binary, seed: int): h1 = seed ^ len(data) h2 = seed >> 32 h1 &= 0xFFFFFFFF h2 &= 0xFFFFFFFF view = memoryview(data) j = len(data) % 4 m = len(data) - j body = view[:m] tail = view[m:] it = iter(chunks.unpack(body, 4)) for k1, k2 in zip_longest(it, it): k1 *= 0x5BD1E995 k1 &= 0xFFFFFFFF k1 ^= k1 >> 24 k1 *= 0x5BD1E995 k1 &= 0xFFFFFFFF h1 *= 0x5BD1E995 h1 &= 0xFFFFFFFF h1 ^= k1 if k2 is None: break k2 *= 0x5BD1E995 k2 &= 0xFFFFFFFF k2 ^= k2 >> 24 k2 *= 0x5BD1E995 k2 &= 0xFFFFFFFF h2 *= 0x5BD1E995 h2 &= 0xFFFFFFFF h2 ^= k2 while j > 0: j -= 1 h2 ^= tail[j] << (j << 3) if tail: h2 *= 0x5BD1E995 h2 &= 0xFFFFFFFF h1 ^= h2 >> 18 h1 *= 0x5BD1E995 h1 &= 0xFFFFFFFF h2 ^= h1 >> 22 h2 *= 0x5BD1E995 h2 &= 0xFFFFFFFF h1 ^= h2 >> 17 h1 *= 0x5BD1E995 h1 &= 0xFFFFFFFF h2 ^= h1 >> 19 h2 *= 0x5BD1E995 h2 &= 0xFFFFFFFF h = (h1 << 32) | h2 return h.to_bytes(8, 'big')
def v2_mmh32digestA_mmix(h, k)
-
Expand source code Browse git
def v2_mmh32digestA_mmix(h, k): k *= 0x5BD1E995 k &= 0xFFFFFFFF k ^= k >> 24 k *= 0x5BD1E995 k &= 0xFFFFFFFF h *= 0x5BD1E995 h &= 0xFFFFFFFF h ^= k return (h, k)
def v2_mmh32digestA(data, seed)
-
Expand source code Browse git
def v2_mmh32digestA(data: Binary, seed: int): n = len(data) h = seed & 0xFFFFFFFF j = len(data) % 4 e = len(data) - j t = 0 view = memoryview(data) body = view[:e] tail = view[e:] for k in chunks.unpack(body, 4): h, k = v2_mmh32digestA_mmix(h, k) while j > 0: j -= 1 t ^= tail[j] << (j << 3) h, t = v2_mmh32digestA_mmix(h, t) h, n = v2_mmh32digestA_mmix(h, n) h ^= h >> 13 h *= 0x5BD1E995 h &= 0xFFFFFFFF h ^= h >> 15 return h.to_bytes(4, 'big')