UNPKG

3.34 kBJavaScriptView Raw
1import { _0n, _1n } from '@polkadot/util';
2import { BigInt } from '@polkadot/x-bigint';
3const P64_1 = BigInt('11400714785074694791');
4const P64_2 = BigInt('14029467366897019727');
5const P64_3 = BigInt('1609587929392839161');
6const P64_4 = BigInt('9650029242287828579');
7const P64_5 = BigInt('2870177450012600261');
8const U64 = BigInt('0xffffffffffffffff');
9const _7n = BigInt(7);
10const _11n = BigInt(11);
11const _12n = BigInt(12);
12const _16n = BigInt(16);
13const _18n = BigInt(18);
14const _23n = BigInt(23);
15const _27n = BigInt(27);
16const _29n = BigInt(29);
17const _31n = BigInt(31);
18const _32n = BigInt(32);
19const _33n = BigInt(33);
20const _64n = BigInt(64);
21const _256n = BigInt(256);
22function rotl(a, b) {
23 const c = a & U64;
24 return ((c << b) | (c >> (_64n - b))) & U64;
25}
26function fromU8a(u8a, p, count) {
27 const bigints = new Array(count);
28 let offset = 0;
29 for (let i = 0; i < count; i++, offset += 2) {
30 bigints[i] = BigInt(u8a[p + offset] | (u8a[p + 1 + offset] << 8));
31 }
32 let result = _0n;
33 for (let i = count - 1; i >= 0; i--) {
34 result = (result << _16n) + bigints[i];
35 }
36 return result;
37}
38function init(seed, input) {
39 const state = {
40 seed,
41 u8a: new Uint8Array(32),
42 u8asize: 0,
43 v1: seed + P64_1 + P64_2,
44 v2: seed + P64_2,
45 v3: seed,
46 v4: seed - P64_1
47 };
48 if (input.length < 32) {
49 state.u8a.set(input);
50 state.u8asize = input.length;
51 return state;
52 }
53 const limit = input.length - 32;
54 let p = 0;
55 if (limit >= 0) {
56 const adjustV = (v) => P64_1 * rotl(v + P64_2 * fromU8a(input, p, 4), _31n);
57 do {
58 state.v1 = adjustV(state.v1);
59 p += 8;
60 state.v2 = adjustV(state.v2);
61 p += 8;
62 state.v3 = adjustV(state.v3);
63 p += 8;
64 state.v4 = adjustV(state.v4);
65 p += 8;
66 } while (p <= limit);
67 }
68 if (p < input.length) {
69 state.u8a.set(input.subarray(p, input.length));
70 state.u8asize = input.length - p;
71 }
72 return state;
73}
74export function xxhash64(input, initSeed) {
75 const { seed, u8a, u8asize, v1, v2, v3, v4 } = init(BigInt(initSeed), input);
76 let p = 0;
77 let h64 = U64 & (BigInt(input.length) + (input.length >= 32
78 ? (((((((((rotl(v1, _1n) + rotl(v2, _7n) + rotl(v3, _12n) + rotl(v4, _18n)) ^ (P64_1 * rotl(v1 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v2 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v3 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v4 * P64_2, _31n))) * P64_1 + P64_4)
79 : (seed + P64_5)));
80 while (p <= (u8asize - 8)) {
81 h64 = U64 & (P64_4 + P64_1 * rotl(h64 ^ (P64_1 * rotl(P64_2 * fromU8a(u8a, p, 4), _31n)), _27n));
82 p += 8;
83 }
84 if ((p + 4) <= u8asize) {
85 h64 = U64 & (P64_3 + P64_2 * rotl(h64 ^ (P64_1 * fromU8a(u8a, p, 2)), _23n));
86 p += 4;
87 }
88 while (p < u8asize) {
89 h64 = U64 & (P64_1 * rotl(h64 ^ (P64_5 * BigInt(u8a[p++])), _11n));
90 }
91 h64 = U64 & (P64_2 * (h64 ^ (h64 >> _33n)));
92 h64 = U64 & (P64_3 * (h64 ^ (h64 >> _29n)));
93 h64 = U64 & (h64 ^ (h64 >> _32n));
94 const result = new Uint8Array(8);
95 for (let i = 7; i >= 0; i--) {
96 result[i] = Number(h64 % _256n);
97 h64 = h64 / _256n;
98 }
99 return result;
100}