algorighm/hash/murmur-hash3.js

54 lines
1.7 KiB
JavaScript

/**
*
* @param {string} key 需要做hash转换的数组
* @param {number} seed 随机种子
* @returns
*/
export default function murmurhash3(key, seed = 0) {
let h1 = seed;
const c1 = 0xcc9e2d51;
const c2 = 0x1b873593;
const len = key.length;
const roundedEnd = len & ~0x3; // round down to 4 byte block
for (let i = 0; i < roundedEnd; i += 4) {
// little endian load order
let k1 = (key.charCodeAt(i) & 0xff)
| ((key.charCodeAt(i + 1) & 0xff) << 8)
| ((key.charCodeAt(i + 2) & 0xff) << 16)
| ((key.charCodeAt(i + 3) & 0xff) << 24);
k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
h1 = (h1 << 13) | (h1 >>> 19);
h1 = (h1 * 5 + 0xe6546b64) & 0xffffffff;
}
// tail
let k1 = 0;
switch (len & 0x3) {
case 3: k1 = (key.charCodeAt(roundedEnd + 2) & 0xff) << 16;
case 2: k1 |= (key.charCodeAt(roundedEnd + 1) & 0xff) << 8;
case 1: k1 |= (key.charCodeAt(roundedEnd) & 0xff);
k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
h1 ^= k1;
}
// finalization
h1 ^= len;
h1 ^= h1 >>> 16;
h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 13;
h1 = (((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff;
h1 ^= h1 >>> 16;
return h1 >>> 0;
}