string-hash.ts 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. /**
  2. * FNV-1a Hash implementation
  3. * @author Travis Webb (tjwebb) <me@traviswebb.com>
  4. *
  5. * Ported from https://github.com/tjwebb/fnv-plus/blob/master/index.js
  6. *
  7. * Simplified, optimized and add modified for 52 bit, which provides a larger hash space
  8. * and still making use of Javascript's 53-bit integer space.
  9. */
  10. export function fnv1a52(str: string) {
  11. const len = str.length;
  12. let i = 0,
  13. t0 = 0,
  14. v0 = 0x2325,
  15. t1 = 0,
  16. v1 = 0x8422,
  17. t2 = 0,
  18. v2 = 0x9CE4,
  19. t3 = 0,
  20. v3 = 0xCBF2;
  21. while (i < len) {
  22. v0 ^= str.charCodeAt(i++);
  23. t0 = v0 * 435;
  24. t1 = v1 * 435;
  25. t2 = v2 * 435;
  26. t3 = v3 * 435;
  27. t2 += v0 << 8;
  28. t3 += v1 << 8;
  29. t1 += t0 >>> 16;
  30. v0 = t0 & 65535;
  31. t2 += t1 >>> 16;
  32. v1 = t1 & 65535;
  33. v3 = (t3 + (t2 >>> 16)) & 65535;
  34. v2 = t2 & 65535;
  35. }
  36. return (
  37. (v3 & 15) * 281_474_976_710_656
  38. + v2 * 4_294_967_296
  39. + v1 * 65536
  40. + (v0 ^ (v3 >> 4))
  41. );
  42. }
  43. export function fnv1a(s: string) {
  44. let h = 0x81_1C_9D_C5;
  45. for (let i = 0, l = s.length; i < l; i++) {
  46. h ^= s.charCodeAt(i);
  47. h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24);
  48. }
  49. return (h >>> 0);
  50. }
  51. export const stringHash = (payload: string) => fnv1a52(payload).toString(36) + payload.length.toString(36);