UNPKG

1.45 kBJavaScriptView Raw
1// Copyright 2017-2022 @polkadot/util authors & contributors
2// SPDX-License-Identifier: Apache-2.0
3import { assert } from "../assert.js";
4import { BN, BN_ONE, BN_TWO, bnToBn, bnToU8a } from "../bn/index.js";
5import { u8aConcat } from "../u8a/index.js";
6const MAX_U8 = BN_TWO.pow(new BN(8 - 2)).isub(BN_ONE);
7const MAX_U16 = BN_TWO.pow(new BN(16 - 2)).isub(BN_ONE);
8const MAX_U32 = BN_TWO.pow(new BN(32 - 2)).isub(BN_ONE);
9const BL_16 = {
10 bitLength: 16
11};
12const BL_32 = {
13 bitLength: 32
14};
15/**
16 * @name compactToU8a
17 * @description Encodes a number into a compact representation
18 * @example
19 * <BR>
20 *
21 * ```javascript
22 * import { compactToU8a } from '@polkadot/util';
23 *
24 * console.log(compactToU8a(511, 32)); // Uint8Array([0b11111101, 0b00000111])
25 * ```
26 */
27
28export function compactToU8a(value) {
29 const bn = bnToBn(value);
30
31 if (bn.lte(MAX_U8)) {
32 return new Uint8Array([bn.toNumber() << 2]);
33 } else if (bn.lte(MAX_U16)) {
34 return bnToU8a(bn.shln(2).iadd(BN_ONE), BL_16);
35 } else if (bn.lte(MAX_U32)) {
36 return bnToU8a(bn.shln(2).iadd(BN_TWO), BL_32);
37 }
38
39 const u8a = bnToU8a(bn);
40 let length = u8a.length; // adjust to the minimum number of bytes
41
42 while (u8a[length - 1] === 0) {
43 length--;
44 }
45
46 assert(length >= 4, 'Invalid length, previous checks match anything less than 2^30');
47 return u8aConcat( // subtract 4 as minimum (also catered for in decoding)
48 [(length - 4 << 2) + 0b11], u8a.subarray(0, length));
49}
\No newline at end of file