muk.js (3905B)
1 // ++ muk 2 // 3 // See arvo/sys/hoon.hoon. 4 5 const BN = require('bn.js') 6 7 const ux_FF = new BN(0xFF) 8 const ux_FF00 = new BN(0xFF00) 9 const u_256 = new BN(256) 10 11 /** 12 * Standard murmur3. 13 * 14 * @param {Number} syd 15 * @param {Number} len 16 * @param {BN} key 17 * @return {BN} 18 */ 19 const muk = (syd, len, key) => { 20 const lo = key.and(ux_FF).toNumber() 21 const hi = key.and(ux_FF00).div(u_256).toNumber() 22 const kee = String.fromCharCode(lo) + String.fromCharCode(hi) 23 return new BN(murmurhash3_32_gc(kee, syd)) 24 } 25 26 // see: https://github.com/garycourt/murmurhash-js 27 // 28 // Copyright (c) 2011 Gary Court 29 // 30 // Permission is hereby granted, free of charge, to any person obtaining a copy of 31 // this software and associated documentation files (the "Software"), to deal in 32 // the Software without restriction, including without limitation the rights to 33 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 34 // of the Software, and to permit persons to whom the Software is furnished to do 35 // so, subject to the following conditions: 36 // 37 // The above copyright notice and this permission notice shall be included in all 38 // copies or substantial portions of the Software. 39 // 40 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 41 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 42 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 43 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 44 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 45 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 46 // SOFTWARE. 47 48 /** 49 * JS Implementation of MurmurHash3 (r136) (as of May 20, 2011) 50 * 51 * @author <a href="mailto:gary.court@gmail.com">Gary Court</a> 52 * @see http://github.com/garycourt/murmurhash-js 53 * @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a> 54 * @see http://sites.google.com/site/murmurhash/ 55 * 56 * @param {string} key ASCII only 57 * @param {number} seed Positive integer only 58 * @return {number} 32-bit positive integer hash 59 **/ 60 const murmurhash3_32_gc = (key, seed) => { 61 // eslint-disable-next-line no-unused-vars 62 let remainder, bytes, h1, h1b, c1, c1b, c2, c2b, k1, i; 63 64 remainder = key.length & 3; // key.length % 4 65 bytes = key.length - remainder; 66 h1 = seed; 67 c1 = 0xcc9e2d51; 68 c2 = 0x1b873593; 69 i = 0; 70 71 while (i < bytes) { 72 k1 = 73 ((key.charCodeAt(i) & 0xff)) | 74 ((key.charCodeAt(++i) & 0xff) << 8) | 75 ((key.charCodeAt(++i) & 0xff) << 16) | 76 ((key.charCodeAt(++i) & 0xff) << 24); 77 ++i; 78 79 k1 = ((((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16))) & 0xffffffff; 80 k1 = (k1 << 15) | (k1 >>> 17); 81 k1 = ((((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16))) & 0xffffffff; 82 83 h1 ^= k1; 84 h1 = (h1 << 13) | (h1 >>> 19); 85 h1b = ((((h1 & 0xffff) * 5) + ((((h1 >>> 16) * 5) & 0xffff) << 16))) & 0xffffffff; 86 h1 = (((h1b & 0xffff) + 0x6b64) + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16)); 87 } 88 89 k1 = 0; 90 91 switch (remainder) { 92 case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16; 93 // eslint-disable-next-line no-fallthrough 94 case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8; 95 // eslint-disable-next-line no-fallthrough 96 case 1: k1 ^= (key.charCodeAt(i) & 0xff); 97 98 k1 = (((k1 & 0xffff) * c1) + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff; 99 k1 = (k1 << 15) | (k1 >>> 17); 100 k1 = (((k1 & 0xffff) * c2) + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff; 101 h1 ^= k1; 102 } 103 104 h1 ^= key.length; 105 106 h1 ^= h1 >>> 16; 107 h1 = (((h1 & 0xffff) * 0x85ebca6b) + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff; 108 h1 ^= h1 >>> 13; 109 h1 = ((((h1 & 0xffff) * 0xc2b2ae35) + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16))) & 0xffffffff; 110 h1 ^= h1 >>> 16; 111 112 return h1 >>> 0; 113 } 114 115 module.exports = { 116 muk 117 }