Skip to content

Instantly share code, notes, and snippets.

@esquinas
Created September 3, 2019 17:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esquinas/a93aea1c9e25a3a5226ea31b4a48b4e8 to your computer and use it in GitHub Desktop.
Save esquinas/a93aea1c9e25a3a5226ea31b4a48b4e8 to your computer and use it in GitHub Desktop.
Quick & simple non-cryptographic 32bit hash function for non-security applications like generating colors from a string or slug. Based on the djb2a algorithm but + UTF16 rotation, + reversal, + XORing a random number.
// Usage:
// djb2eHash( 'Hello World1' ); # => 1171219298
// djb2eHash( 'Hello World2' ); # => 449666786
// djb2eHash( 'Hello World3' ); # => 201925602
// djb2eHash( 'Hello World4' ); # => 3033001186
function djb2eHash(string, randomNumber = 0xcde7) {
// UTF16-rotate a character.
function rotU16(charCode) {
return 0x10000 - charCode;
}
const gnirts = string.split('').reverse().join('');
let hash = 5381; // Important magic number.
let limit = 0xffffffff; // 32-bit mask.
for (let i = 0; i < string.length; i++) {
// Normal string |> djb2a .
// hash = hash * 33 XOR charCode (bound into 32bits).
hash = (((hash << 5) + hash) ^ string.charCodeAt(i)) & limit;
// Normal string |> reverse |> djb2a .
hash = (((hash << 5) + hash) ^ gnirts.charCodeAt(i)) & limit;
// Normal string |> rotate |> djb2a .
hash = (((hash << 5) + hash) ^ rotU16(string.charCodeAt(i))) & limit;
// Normal string |> reverse |> rotate |> djb2a .
hash = (((hash << 5) + hash) ^ rotU16(gnirts.charCodeAt(i))) & limit;
}
// XOR with a random number to improve the results on small strings
// and return a 32-bit number.
return (hash ^ randomNumber) >>> 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment