UNPKG

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