/* eslint-disable no-fallthrough */ import { UTF16ToUTF8, x86Fmix, x86Multiply, x86Rotl } from './common'; /*! * +----------------------------------------------------------------------------------+ * | murmurHash3.js v3.0.0 (http://github.com/karanlyons/murmurHash3.js) | * | A TypeScript/JavaScript implementation of MurmurHash3's hashing algorithms. | * |----------------------------------------------------------------------------------| * | Copyright (c) 2012-2020 Karan Lyons. Freely distributable under the MIT license. | * +----------------------------------------------------------------------------------+ */ // PUBLIC FUNCTIONS // ---------------- function hash128x86(key?: string, seed?: number): string { // // Given a string and an optional seed as an int, returns a 128 bit // hash using the x86 flavor of MurmurHash3, as an unsigned hex. // key = key || ''; seed = seed || 0; var remainder = key.length % 16; var bytes = key.length - remainder; var h1 = seed; var h2 = seed; var h3 = seed; var h4 = seed; var k1 = 0; var k2 = 0; var k3 = 0; var k4 = 0; var c1 = 0x239b961b; var c2 = 0xab0e9789; var c3 = 0x38b34ae5; var c4 = 0xa1e38b93; for (var i = 0; i < bytes; i = i + 16) { k1 = ((key.charCodeAt(i) & 0xff)) | ((key.charCodeAt(i + 1) & 0xff) << 8) | ((key.charCodeAt(i + 2) & 0xff) << 16) | ((key.charCodeAt(i + 3) & 0xff) << 24); k2 = ((key.charCodeAt(i + 4) & 0xff)) | ((key.charCodeAt(i + 5) & 0xff) << 8) | ((key.charCodeAt(i + 6) & 0xff) << 16) | ((key.charCodeAt(i + 7) & 0xff) << 24); k3 = ((key.charCodeAt(i + 8) & 0xff)) | ((key.charCodeAt(i + 9) & 0xff) << 8) | ((key.charCodeAt(i + 10) & 0xff) << 16) | ((key.charCodeAt(i + 11) & 0xff) << 24); k4 = ((key.charCodeAt(i + 12) & 0xff)) | ((key.charCodeAt(i + 13) & 0xff) << 8) | ((key.charCodeAt(i + 14) & 0xff) << 16) | ((key.charCodeAt(i + 15) & 0xff) << 24); k1 = x86Multiply(k1, c1); k1 = x86Rotl(k1, 15); k1 = x86Multiply(k1, c2); h1 ^= k1; h1 = x86Rotl(h1, 19); h1 += h2; h1 = x86Multiply(h1, 5) + 0x561ccd1b; k2 = x86Multiply(k2, c2); k2 = x86Rotl(k2, 16); k2 = x86Multiply(k2, c3); h2 ^= k2; h2 = x86Rotl(h2, 17); h2 += h3; h2 = x86Multiply(h2, 5) + 0x0bcaa747; k3 = x86Multiply(k3, c3); k3 = x86Rotl(k3, 17); k3 = x86Multiply(k3, c4); h3 ^= k3; h3 = x86Rotl(h3, 15); h3 += h4; h3 = x86Multiply(h3, 5) + 0x96cd1c35; k4 = x86Multiply(k4, c4); k4 = x86Rotl(k4, 18); k4 = x86Multiply(k4, c1); h4 ^= k4; h4 = x86Rotl(h4, 13); h4 += h1; h4 = x86Multiply(h4, 5) + 0x32ac3b17; } k1 = 0; k2 = 0; k3 = 0; k4 = 0; switch (remainder) { case 15: k4 ^= key.charCodeAt(i + 14) << 16; case 14: k4 ^= key.charCodeAt(i + 13) << 8; case 13: k4 ^= key.charCodeAt(i + 12); k4 = x86Multiply(k4, c4); k4 = x86Rotl(k4, 18); k4 = x86Multiply(k4, c1); h4 ^= k4; case 12: k3 ^= key.charCodeAt(i + 11) << 24; case 11: k3 ^= key.charCodeAt(i + 10) << 16; case 10: k3 ^= key.charCodeAt(i + 9) << 8; case 9: k3 ^= key.charCodeAt(i + 8); k3 = x86Multiply(k3, c3); k3 = x86Rotl(k3, 17); k3 = x86Multiply(k3, c4); h3 ^= k3; case 8: k2 ^= key.charCodeAt(i + 7) << 24; case 7: k2 ^= key.charCodeAt(i + 6) << 16; case 6: k2 ^= key.charCodeAt(i + 5) << 8; case 5: k2 ^= key.charCodeAt(i + 4); k2 = x86Multiply(k2, c2); k2 = x86Rotl(k2, 16); k2 = x86Multiply(k2, c3); h2 ^= k2; case 4: k1 ^= key.charCodeAt(i + 3) << 24; case 3: k1 ^= key.charCodeAt(i + 2) << 16; case 2: k1 ^= key.charCodeAt(i + 1) << 8; case 1: k1 ^= key.charCodeAt(i); k1 = x86Multiply(k1, c1); k1 = x86Rotl(k1, 15); k1 = x86Multiply(k1, c2); h1 ^= k1; } h1 ^= key.length; h2 ^= key.length; h3 ^= key.length; h4 ^= key.length; h1 += h2; h1 += h3; h1 += h4; h2 += h1; h3 += h1; h4 += h1; h1 = x86Fmix(h1); h2 = x86Fmix(h2); h3 = x86Fmix(h3); h4 = x86Fmix(h4); h1 += h2; h1 += h3; h1 += h4; h2 += h1; h3 += h1; h4 += h1; return ('00000000' + (h1 >>> 0).toString(16)).slice(-8) + ('00000000' + (h2 >>> 0).toString(16)).slice(-8) + ('00000000' + (h3 >>> 0).toString(16)).slice(-8) + ('00000000' + (h4 >>> 0).toString(16)).slice(-8); } /** * x86 version of Murmur3 for 128bits. * Used by hashImpression128 because in JS it is more efficient than the x64 version, no matter the underlying OS/CPU arch. * * @param str - The string to hash. */ export function hash128(str: string, seed?: number): string { return hash128x86(UTF16ToUTF8(str), (seed as number) >>> 0); }