Skip to content

Instantly share code, notes, and snippets.

@kripod
Last active February 20, 2020 22:58
Show Gist options
  • Save kripod/7fb9cad2f58b5164ff09e3d3436def22 to your computer and use it in GitHub Desktop.
Save kripod/7fb9cad2f58b5164ff09e3d3436def22 to your computer and use it in GitHub Desktop.
MurmurHash2 in TypeScript
/* eslint-disable no-fallthrough */
// Inspired by: https://github.com/levitation/murmurhash-js
export default function murmur2(data: string, seed: number = 0): number {
// 'm' and 'r' are mixing constants generated offline.
// They're not really 'magic', they just happen to work well.
// const m = 0x5bd1e995;
// const r = 24;
let k,
i = 0,
len = data.length,
nBlocks = len >>> 2;
// Initialize the hash to a 'random' value
seed ^= len;
// Mix 4 bytes at a time into the hash
for (; nBlocks--; ++i) {
k =
(data.charCodeAt(i) & 0xff) |
((data.charCodeAt(++i) & 0xff) << 8) |
((data.charCodeAt(++i) & 0xff) << 16) |
((data.charCodeAt(++i) & 0xff) << 24);
k = /* Math.imul(k, m): */ ((k * 0x5bd1) << 16) + k * 0xe995;
k ^= /* k >>> r: */ k >>> 24;
seed =
/* Math.imul(seed, m): */ (((seed * 0x5bd1) << 16) + seed * 0xe995) ^
/* Math.imul(k, m): */ (((k * 0x5bd1) << 16) + k * 0xe995);
}
// Handle the last few bytes of the input array
switch (len & 3) {
case 3:
seed ^= (data.charCodeAt(i + 2) & 0xff) << 16;
case 2:
seed ^= (data.charCodeAt(i + 1) & 0xff) << 8;
case 1:
seed ^= data.charCodeAt(i) & 0xff;
seed = /* Math.imul(seed, m): */ ((seed * 0x5bd1) << 16) + seed * 0xe995;
}
// Do a few final mixes of the hash to ensure the last few
// bytes are well-incorporated.
seed ^= seed >>> 13;
seed = /* Math.imul(seed, m): */ ((seed * 0x5bd1) << 16) + seed * 0xe995;
return (seed ^ (seed >>> 15)) >>> 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment