fnv1a.js 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. 'use strict';
  2. const Long = require('./long');
  3. const MASK_8 = 0xff;
  4. const MASK_24 = 0xffffff;
  5. const MASK_32 = 0xffffffff;
  6. // See http://www.isthe.com/chongo/tech/comp/fnv/#FNV-param for the definition of these parameters;
  7. const FNV_PRIME = new Long(16777619, 0);
  8. const OFFSET_BASIS = new Long(2166136261, 0);
  9. const FNV_MASK = new Long(MASK_32, 0);
  10. /**
  11. * Implementation of the FNV-1a hash for a 32-bit hash value
  12. * Algorithm can be found here: http://www.isthe.com/chongo/tech/comp/fnv/#FNV-1a
  13. * @ignore
  14. */
  15. function fnv1a32(input, encoding) {
  16. encoding = encoding || 'utf8';
  17. const octets = Buffer.from(input, encoding);
  18. let hash = OFFSET_BASIS;
  19. for (let i = 0; i < octets.length; i += 1) {
  20. hash = hash.xor(new Long(octets[i], 0));
  21. hash = hash.multiply(FNV_PRIME);
  22. hash = hash.and(FNV_MASK);
  23. }
  24. return hash.getLowBitsUnsigned();
  25. }
  26. /**
  27. * Implements FNV-1a to generate 32-bit hash, then uses xor-folding
  28. * to convert to a 24-bit hash. See here for more info:
  29. * http://www.isthe.com/chongo/tech/comp/fnv/#xor-fold
  30. * @ignore
  31. */
  32. function fnv1a24(input, encoding) {
  33. const _32bit = fnv1a32(input, encoding);
  34. const base = _32bit & MASK_24;
  35. const top = (_32bit >>> 24) & MASK_8;
  36. const final = (base ^ top) & MASK_24;
  37. return final;
  38. }
  39. module.exports = { fnv1a24, fnv1a32 };