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