54 lines
1.7 KiB
JavaScript
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;
|
|
}
|