Skip to content

Instantly share code, notes, and snippets.

@CryptoManiac
Created December 3, 2019 17:33
Show Gist options
  • Save CryptoManiac/1fc7c37f9e095e59532dfbc99f3ecf8e to your computer and use it in GitHub Desktop.
Save CryptoManiac/1fc7c37f9e095e59532dfbc99f3ecf8e to your computer and use it in GitHub Desktop.
'use strict';
// Calculate N * 160 bits of hash value.
// Based on murmurhash160 by bryc (github.com/bryc)
// From: https://simonhf.wordpress.com/2010/09/25/murmurhash160/
function hash(key, bits=480) {
let result = Buffer.alloc(bits / 8);
for (let step = 0; step < bits / 160; ++step) {
let k;
const m1 = 1540483477, m2 = 433494437, m3 = 2971215073, m4 = 370248451, m5 = 1405695061;
let h1 = key.length ^ step, h2 = h1 ^ m2, h3 = h1 ^ m3, h4 = h1 ^ m4, h5 = h1 ^ m5;
let i, b;
for (i = 0, b = key.length & -4; i < b; i += 4) {
k = key[i + 3] << 24 | key[i + 2] << 16 | key[i + 1] << 8 | key[i];
k = Math.imul(k, m1);
k ^= k >>> 24;
k = Math.imul(k, m1);
h1 = Math.imul(h1, m1) ^ k ^ h2;
h2 = Math.imul(h2, m2) ^ k ^ h3;
h3 = Math.imul(h3, m3) ^ k ^ h4;
h4 = Math.imul(h4, m4) ^ k ^ h5;
h5 = Math.imul(h5, m5) ^ k ^ h1;
}
switch (key.length & 3) {
case 3:
h1 ^= key[i + 2] << 16;
h2 ^= key[i + 2] << 16;
h3 ^= key[i + 2] << 16;
h4 ^= key[i + 2] << 16;
h5 ^= key[i + 2] << 16;
case 2:
h1 ^= key[i + 1] << 8;
h2 ^= key[i + 1] << 8;
h3 ^= key[i + 1] << 8;
h4 ^= key[i + 1] << 8;
h5 ^= key[i + 1] << 8;
case 1:
h1 ^= key[i];
h2 ^= key[i];
h3 ^= key[i];
h4 ^= key[i];
h5 ^= key[i];
h1 = Math.imul(h1, m1);
h2 = Math.imul(h2, m2);
h3 = Math.imul(h3, m3);
h4 = Math.imul(h4, m4);
h5 = Math.imul(h5, m5);
}
h1 ^= h1 >>> 13, h1 = Math.imul(h1, m1), h1 ^= h1 >>> 15;
h2 ^= h2 >>> 13, h2 = Math.imul(h2, m2), h2 ^= h2 >>> 15;
h3 ^= h3 >>> 13, h3 = Math.imul(h3, m3), h3 ^= h3 >>> 15;
h4 ^= h4 >>> 13, h4 = Math.imul(h4, m4), h4 ^= h4 >>> 15;
h5 ^= h5 >>> 13, h5 = Math.imul(h5, m5), h5 ^= h5 >>> 15;
result.writeUInt32LE((h1 ^ h2 ^ h3 ^ h4 ^ h5) >>> 0, step * 20);
result.writeUInt32LE((h2 ^ h1) >>> 0, step * 20 + 4);
result.writeUInt32LE((h3 ^ h1) >>> 0, step * 20 + 8);
result.writeUInt32LE((h4 ^ h1) >>> 0, step * 20 + 12);
result.writeUInt32LE((h5 ^ h1) >>> 0, step * 20 + 16);
}
return result;
}
module.exports = hash;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment