From cd8d87f02be5c8f089eb0e287e2cf0296c8777df Mon Sep 17 00:00:00 2001 From: Lewis Liu Date: Fri, 2 Jun 2023 17:26:32 -0700 Subject: [PATCH] Try djb2 hash --- src/basic/hash-murmur.js | 88 ++++++++++++++++++++++++++++++++++++++++ src/basic/hash.js | 72 ++------------------------------ 2 files changed, 91 insertions(+), 69 deletions(-) create mode 100644 src/basic/hash-murmur.js diff --git a/src/basic/hash-murmur.js b/src/basic/hash-murmur.js new file mode 100644 index 0000000..730b56e --- /dev/null +++ b/src/basic/hash-murmur.js @@ -0,0 +1,88 @@ +// Copied from https://github.com/emotion-js/emotion/blob/master/packages/hash/src/index.js + +const murmur2 = (str) => { + // 'm' and 'r' are mixing constants generated offline. + // They're not really 'magic', they just happen to work well. + + // const m = 0x5bd1e995; + // const r = 24; + + // Initialize the hash + + var h = 0; + + // Mix 4 bytes at a time into the hash + + var k, + i = 0, + len = str.length; + for (; len >= 4; ++i, len -= 4) { + k = + (str.charCodeAt(i) & 0xff) | + ((str.charCodeAt(++i) & 0xff) << 8) | + ((str.charCodeAt(++i) & 0xff) << 16) | + ((str.charCodeAt(++i) & 0xff) << 24); + + k = + /* Math.imul(k, m): */ + (k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0xe995) << 16); + k ^= /* k >>> r: */ k >>> 24; + + h = + /* Math.imul(k, m): */ + ((k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0xe995) << 16)) ^ + /* Math.imul(h, m): */ + ((h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0xe995) << 16)); + } + + // Handle the last few bytes of the input array + + switch (len) { + case 3: + h ^= (str.charCodeAt(i + 2) & 0xff) << 16; + case 2: + h ^= (str.charCodeAt(i + 1) & 0xff) << 8; + case 1: + h ^= str.charCodeAt(i) & 0xff; + h = + /* Math.imul(h, m): */ + (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0xe995) << 16); + } + + // Do a few final mixes of the hash to ensure the last few + // bytes are well-incorporated. + + h ^= h >>> 13; + h = + /* Math.imul(h, m): */ + (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0xe995) << 16); + + return ((h ^ (h >>> 15)) >>> 0).toString(36); +} + +// Copied from https://github.com/styled-components/styled-components/blob/master/packages/styled-components/src/utils/hash.js + +const SEED = 5381; + +// When we have separate strings it's useful to run a progressive +// version of djb2 where we pretend that we're still looping over +// the same string +const phash = (h, x) => { + let i = x.length; + + while (i) { + h = (h * 33) ^ x.charCodeAt(--i); + } + + return h; +}; + +// This is a djb2 hashing function +const hash = (x) => { + return phash(SEED, x); +}; + +// switch between readable vs faster & smaller classnames depending on environment +const readableHash = (value) => CSS.escape(value).replace(/\\./g, '_') + +export default murmur2 \ No newline at end of file diff --git a/src/basic/hash.js b/src/basic/hash.js index 730b56e..6ad5fd3 100644 --- a/src/basic/hash.js +++ b/src/basic/hash.js @@ -1,67 +1,4 @@ -// Copied from https://github.com/emotion-js/emotion/blob/master/packages/hash/src/index.js - -const murmur2 = (str) => { - // 'm' and 'r' are mixing constants generated offline. - // They're not really 'magic', they just happen to work well. - - // const m = 0x5bd1e995; - // const r = 24; - - // Initialize the hash - - var h = 0; - - // Mix 4 bytes at a time into the hash - - var k, - i = 0, - len = str.length; - for (; len >= 4; ++i, len -= 4) { - k = - (str.charCodeAt(i) & 0xff) | - ((str.charCodeAt(++i) & 0xff) << 8) | - ((str.charCodeAt(++i) & 0xff) << 16) | - ((str.charCodeAt(++i) & 0xff) << 24); - - k = - /* Math.imul(k, m): */ - (k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0xe995) << 16); - k ^= /* k >>> r: */ k >>> 24; - - h = - /* Math.imul(k, m): */ - ((k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0xe995) << 16)) ^ - /* Math.imul(h, m): */ - ((h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0xe995) << 16)); - } - - // Handle the last few bytes of the input array - - switch (len) { - case 3: - h ^= (str.charCodeAt(i + 2) & 0xff) << 16; - case 2: - h ^= (str.charCodeAt(i + 1) & 0xff) << 8; - case 1: - h ^= str.charCodeAt(i) & 0xff; - h = - /* Math.imul(h, m): */ - (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0xe995) << 16); - } - - // Do a few final mixes of the hash to ensure the last few - // bytes are well-incorporated. - - h ^= h >>> 13; - h = - /* Math.imul(h, m): */ - (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0xe995) << 16); - - return ((h ^ (h >>> 15)) >>> 0).toString(36); -} - -// Copied from https://github.com/styled-components/styled-components/blob/master/packages/styled-components/src/utils/hash.js - +// Copied from https://github.com/styled-components/styled-components/blob/3ee575eddf804e4bf460f1cadb5890db7ae2f5cf/packages/styled-components/src/utils/hash.ts#L6 const SEED = 5381; // When we have separate strings it's useful to run a progressive @@ -78,11 +15,8 @@ const phash = (h, x) => { }; // This is a djb2 hashing function -const hash = (x) => { +const hash = x => { return phash(SEED, x); }; -// switch between readable vs faster & smaller classnames depending on environment -const readableHash = (value) => CSS.escape(value).replace(/\\./g, '_') - -export default murmur2 \ No newline at end of file +export default hash;