UNPKG

murmurhash3-ts

Version:
502 lines 15.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.murmurhash = exports.strToBuf = exports.bufToHex = void 0; const strToBuf = TextEncoder.prototype.encode.bind(new TextEncoder()); exports.strToBuf = strToBuf; const hexLUT = Array.from({ length: 256 }, (_, i) => `00${i.toString(16)}`.slice(-2)); function bufToHex(buf = new Uint8Array(0)) { let str = ""; for (let i = 0; i < buf.byteLength; i++) { str += hexLUT[buf[i]]; } return str; } exports.bufToHex = bufToHex; function mul32(m, n) { return (m & 0xffff) * n + ((((m >>> 16) * n) & 0xffff) << 16); } function rol32(n, r) { return (n << r) | (n >>> (32 - r)); } function add64(m, n) { const ms = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff]; const ns = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff]; const os = [0x0, 0x0, 0x0, 0x0]; os[3] += ms[3] + ns[3]; os[2] += os[3] >>> 16; os[3] &= 0xffff; os[2] += ms[2] + ns[2]; os[1] += os[2] >>> 16; os[2] &= 0xffff; os[1] += ms[1] + ns[1]; os[0] += os[1] >>> 16; os[1] &= 0xffff; os[0] += ms[0] + ns[0]; os[0] &= 0xffff; return [(os[0] << 16) | os[1], (os[2] << 16) | os[3]]; } function mul64(m, n) { const ms = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff]; const ns = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff]; const os = [0x0, 0x0, 0x0, 0x0]; os[3] += ms[3] * ns[3]; os[2] += os[3] >>> 16; os[3] &= 0xffff; os[2] += ms[2] * ns[3]; os[1] += os[2] >>> 16; os[2] &= 0xffff; os[2] += ms[3] * ns[2]; os[1] += os[2] >>> 16; os[2] &= 0xffff; os[1] += ms[1] * ns[3]; os[0] += os[1] >>> 16; os[1] &= 0xffff; os[1] += ms[2] * ns[2]; os[0] += os[1] >>> 16; os[1] &= 0xffff; os[1] += ms[3] * ns[1]; os[0] += os[1] >>> 16; os[1] &= 0xffff; os[0] += ms[0] * ns[3] + ms[1] * ns[2] + ms[2] * ns[1] + ms[3] * ns[0]; os[0] &= 0xffff; return [(os[0] << 16) | os[1], (os[2] << 16) | os[3]]; } function rol64(n, r) { r %= 64; if (r === 32) { return [n[1], n[0]]; } else if (r < 32) { return [(n[0] << r) | (n[1] >>> (32 - r)), (n[1] << r) | (n[0] >>> (32 - r))]; } else { r -= 32; return [(n[1] << r) | (n[0] >>> (32 - r)), (n[0] << r) | (n[1] >>> (32 - r))]; } } function shl64(n, s) { s %= 64; if (s === 0) { return n; } else if (s < 32) { return [(n[0] << s) | (n[1] >>> (32 - s)), n[1] << s]; } else { return [n[1] << (s - 32), 0x0]; } } function xor64(a, b) { return [a[0] ^ b[0], a[1] ^ b[1]]; } function x86fmix32(h) { h ^= h >>> 16; h = mul32(h, 0x85ebca6b); h ^= h >>> 13; h = mul32(h, 0xc2b2ae35); h ^= h >>> 16; return h; } const x86hash32c1 = 0xcc9e2d51; const x86hash32c2 = 0x1b873593; function x86mix32(h, k) { k = mul32(k, x86hash32c1); k = rol32(k, 15); k = mul32(k, x86hash32c2); h ^= k; h = rol32(h, 13); h = mul32(h, 5) + 0xe6546b64; return h; } function x86hash32(buf = new Uint8Array(0), state = 0x0, finalize = true) { if (typeof buf === "string") { buf = strToBuf(buf); } let h1; let i; let len; if (typeof state === "number") { h1 = state; i = 0; len = 0; } else { ({ h1, len } = state); const rem = state.rem; if (rem.byteLength === 0) { i = 0; } else if (rem.byteLength + buf.byteLength >= 4) { len += 4; i = 4 - rem.byteLength; const blk = new Uint8Array(4); const dtv = new DataView(blk.buffer); blk.set(rem); blk.set(buf.subarray(0, i), rem.byteLength); h1 = x86mix32(h1, dtv.getUint32(0, true)); } else { const newBuf = new Uint8Array(buf.byteLength + rem.byteLength); newBuf.set(rem); newBuf.set(buf, rem.byteLength); buf = newBuf; i = 0; } } const dtv = new DataView(buf.buffer, buf.byteOffset); const remainder = (buf.byteLength - i) % 4; const bytes = buf.byteLength - i - remainder; len += bytes; for (; i < bytes; i += 4) { h1 = x86mix32(h1, dtv.getUint32(i, true)); } if (!finalize) { return { h1, len, rem: buf.slice(buf.byteLength - remainder), }; } else { len += remainder; let k1 = 0x0; switch (remainder) { case 3: k1 ^= buf[i + 2] << 16; case 2: k1 ^= buf[i + 1] << 8; case 1: k1 ^= buf[i]; k1 = mul32(k1, x86hash32c1); k1 = rol32(k1, 15); k1 = mul32(k1, x86hash32c2); h1 ^= k1; } h1 ^= len & 0xffffffff; h1 = x86fmix32(h1); return h1 >>> 0; } } const x86hash128c1 = 0x239b961b; const x86hash128c2 = 0xab0e9789; const x86hash128c3 = 0x38b34ae5; const x86hash128c4 = 0xa1e38b93; function x86mix128(h1, h2, h3, h4, k1, k2, k3, k4) { k1 = mul32(k1, x86hash128c1); k1 = rol32(k1, 15); k1 = mul32(k1, x86hash128c2); h1 ^= k1; h1 = rol32(h1, 19); h1 += h2; h1 = mul32(h1, 5) + 0x561ccd1b; k2 = mul32(k2, x86hash128c2); k2 = rol32(k2, 16); k2 = mul32(k2, x86hash128c3); h2 ^= k2; h2 = rol32(h2, 17); h2 += h3; h2 = mul32(h2, 5) + 0x0bcaa747; k3 = mul32(k3, x86hash128c3); k3 = rol32(k3, 17); k3 = mul32(k3, x86hash128c4); h3 ^= k3; h3 = rol32(h3, 15); h3 += h4; h3 = mul32(h3, 5) + 0x96cd1c35; k4 = mul32(k4, x86hash128c4); k4 = rol32(k4, 18); k4 = mul32(k4, x86hash128c1); h4 ^= k4; h4 = rol32(h4, 13); h4 += h1; h4 = mul32(h4, 5) + 0x32ac3b17; return [h1, h2, h3, h4]; } function x86hash128(buf = new Uint8Array(0), state = 0x0, finalize = true) { let str; if (typeof buf === "string") { buf = strToBuf(buf); str = true; } else { str = false; } let h1; let h2; let h3; let h4; let i; let len; if (typeof state === "number") { h1 = h2 = h3 = h4 = state; i = 0; len = 0; } else { ({ h1, h2, h3, h4, len } = state); const rem = state.rem; if (rem.byteLength === 0) { i = 0; } else if (rem.byteLength + buf.byteLength >= 16) { len += 16; i = 16 - rem.byteLength; const blk = new Uint8Array(16); const dtv = new DataView(blk.buffer); blk.set(rem); blk.set(buf.subarray(0, i), rem.byteLength); [h1, h2, h3, h4] = x86mix128(h1, h2, h3, h4, dtv.getUint32(0, true), dtv.getUint32(4, true), dtv.getUint32(8, true), dtv.getUint32(12, true)); } else { const newBuf = new Uint8Array(buf.byteLength + rem.byteLength); newBuf.set(rem); newBuf.set(buf, rem.byteLength); buf = newBuf; i = 0; } } const dtv = new DataView(buf.buffer, buf.byteOffset); const remainder = (buf.byteLength - i) % 16; const bytes = buf.byteLength - i - remainder; len += bytes; for (; i < bytes; i += 16) { [h1, h2, h3, h4] = x86mix128(h1, h2, h3, h4, dtv.getUint32(i, true), dtv.getUint32(i + 4, true), dtv.getUint32(i + 8, true), dtv.getUint32(i + 12, true)); } if (!finalize) { return { h1, h2, h3, h4, len, rem: buf.subarray(buf.byteLength - remainder), }; } else { len += remainder; let k1 = 0x0; let k2 = 0x0; let k3 = 0x0; let k4 = 0x0; switch (remainder) { case 15: k4 ^= buf[i + 14] << 16; case 14: k4 ^= buf[i + 13] << 8; case 13: k4 ^= buf[i + 12]; k4 = mul32(k4, x86hash128c4); k4 = rol32(k4, 18); k4 = mul32(k4, x86hash128c1); h4 ^= k4; case 12: k3 ^= buf[i + 11] << 24; case 11: k3 ^= buf[i + 10] << 16; case 10: k3 ^= buf[i + 9] << 8; case 9: k3 ^= buf[i + 8]; k3 = mul32(k3, x86hash128c3); k3 = rol32(k3, 17); k3 = mul32(k3, x86hash128c4); h3 ^= k3; case 8: k2 ^= buf[i + 7] << 24; case 7: k2 ^= buf[i + 6] << 16; case 6: k2 ^= buf[i + 5] << 8; case 5: k2 ^= buf[i + 4]; k2 = mul32(k2, x86hash128c2); k2 = rol32(k2, 16); k2 = mul32(k2, x86hash128c3); h2 ^= k2; case 4: k1 ^= buf[i + 3] << 24; case 3: k1 ^= buf[i + 2] << 16; case 2: k1 ^= buf[i + 1] << 8; case 1: k1 ^= buf[i]; k1 = mul32(k1, x86hash128c1); k1 = rol32(k1, 15); k1 = mul32(k1, x86hash128c2); h1 ^= k1; } h1 ^= len & 0xffffffff; h2 ^= len & 0xffffffff; h3 ^= len & 0xffffffff; h4 ^= len & 0xffffffff; h1 += h2 + h3 + h4; h2 += h1; h3 += h1; h4 += h1; h1 = x86fmix32(h1); h2 = x86fmix32(h2); h3 = x86fmix32(h3); h4 = x86fmix32(h4); h1 += h2 + h3 + h4; h2 += h1; h3 += h1; h4 += h1; const hash = new DataView(new ArrayBuffer(16)); hash.setUint32(0, h1, false); hash.setUint32(4, h2, false); hash.setUint32(8, h3, false); hash.setUint32(12, h4, false); return str ? bufToHex(new Uint8Array(hash.buffer)) : new Uint8Array(hash.buffer); } } const x86 = { hash32: x86hash32, hash128: x86hash128 }; function x64fmix64(h) { h = xor64(h, [0x0, h[0] >>> 1]); h = mul64(h, [0xff51afd7, 0xed558ccd]); h = xor64(h, [0x0, h[0] >>> 1]); h = mul64(h, [0xc4ceb9fe, 0x1a85ec53]); h = xor64(h, [0x0, h[0] >>> 1]); return h; } const x64hash128c1 = [0x87c37b91, 0x114253d5]; const x64hash128c2 = [0x4cf5ad43, 0x2745937f]; function x64mix128(h1, h2, k1, k2) { k1 = mul64(k1, x64hash128c1); k1 = rol64(k1, 31); k1 = mul64(k1, x64hash128c2); h1 = xor64(h1, k1); h1 = rol64(h1, 27); h1 = add64(h1, h2); h1 = add64(mul64(h1, [0x0, 5]), [0x0, 0x52dce729]); k2 = mul64(k2, x64hash128c2); k2 = rol64(k2, 33); k2 = mul64(k2, x64hash128c1); h2 = xor64(h2, k2); h2 = rol64(h2, 31); h2 = add64(h2, h1); h2 = add64(mul64(h2, [0x0, 5]), [0x0, 0x38495ab5]); return [h1, h2]; } function x64hash128(buf = new Uint8Array(0), state = 0x0, finalize = true) { let str; if (typeof buf === "string") { buf = strToBuf(buf); str = true; } else { str = false; } let h1; let h2; let i; let len; if (typeof state === "number") { h1 = [0x0, state]; h2 = [0x0, state]; i = 0; len = 0; } else { ({ h1, h2, len } = state); const rem = state.rem; if (rem.byteLength === 0) { i = 0; } else if (rem.byteLength + buf.byteLength >= 16) { len += 16; i = 16 - rem.byteLength; const blk = new Uint8Array(16); const dtv = new DataView(blk.buffer); blk.set(rem); blk.set(buf.subarray(0, i), rem.byteLength); [h1, h2] = x64mix128(h1, h2, [dtv.getUint32(4, true), dtv.getUint32(0, true)], [dtv.getUint32(12, true), dtv.getUint32(8, true)]); } else { const newBuf = new Uint8Array(buf.byteLength + rem.byteLength); newBuf.set(rem); newBuf.set(buf, rem.byteLength); buf = newBuf; i = 0; } } const dtv = new DataView(buf.buffer, buf.byteOffset); const remainder = (buf.byteLength - i) % 16; const bytes = buf.byteLength - i - remainder; len += bytes; for (; i < bytes; i += 16) { [h1, h2] = x64mix128(h1, h2, [dtv.getUint32(i + 4, true), dtv.getUint32(i, true)], [dtv.getUint32(i + 12, true), dtv.getUint32(i + 8, true)]); } if (!finalize) { return { h1, h2, len, rem: buf.subarray(buf.byteLength - remainder), }; } else { len += remainder; let k1 = [0x0, 0x0]; let k2 = [0x0, 0x0]; switch (remainder) { case 15: k2 = xor64(k2, shl64([0x0, buf[i + 14]], 48)); case 14: k2 = xor64(k2, shl64([0x0, buf[i + 13]], 40)); case 13: k2 = xor64(k2, shl64([0x0, buf[i + 12]], 32)); case 12: k2 = xor64(k2, shl64([0x0, buf[i + 11]], 24)); case 11: k2 = xor64(k2, shl64([0x0, buf[i + 10]], 16)); case 10: k2 = xor64(k2, shl64([0x0, buf[i + 9]], 8)); case 9: k2 = xor64(k2, [0x0, buf[i + 8]]); k2 = mul64(k2, x64hash128c2); k2 = rol64(k2, 33); k2 = mul64(k2, x64hash128c1); h2 = xor64(h2, k2); case 8: k1 = xor64(k1, shl64([0x0, buf[i + 7]], 56)); case 7: k1 = xor64(k1, shl64([0x0, buf[i + 6]], 48)); case 6: k1 = xor64(k1, shl64([0x0, buf[i + 5]], 40)); case 5: k1 = xor64(k1, shl64([0x0, buf[i + 4]], 32)); case 4: k1 = xor64(k1, shl64([0x0, buf[i + 3]], 24)); case 3: k1 = xor64(k1, shl64([0x0, buf[i + 2]], 16)); case 2: k1 = xor64(k1, shl64([0x0, buf[i + 1]], 8)); case 1: k1 = xor64(k1, [0x0, buf[i]]); k1 = mul64(k1, x64hash128c1); k1 = rol64(k1, 31); k1 = mul64(k1, x64hash128c2); h1 = xor64(h1, k1); } h1 = xor64(h1, [0x0, len & 0xffffffff]); h2 = xor64(h2, [0x0, len & 0xffffffff]); h1 = add64(h1, h2); h2 = add64(h2, h1); h1 = x64fmix64(h1); h2 = x64fmix64(h2); h1 = add64(h1, h2); h2 = add64(h2, h1); const hash = new DataView(new ArrayBuffer(16)); hash.setUint32(0, h1[0], false); hash.setUint32(4, h1[1], false); hash.setUint32(8, h2[0], false); hash.setUint32(12, h2[1], false); return str ? bufToHex(new Uint8Array(hash.buffer)) : new Uint8Array(hash.buffer); } } const x64 = { hash128: x64hash128 }; const murmurhash = { x86, x64 }; exports.murmurhash = murmurhash; exports.default = murmurhash; //# sourceMappingURL=index.js.map