1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.u8aToBn = void 0;
|
4 | const bn_js_1 = require("../bn/bn.js");
|
5 | /**
|
6 | * @name u8aToBn
|
7 | * @summary Creates a BN from a Uint8Array object.
|
8 | * @description
|
9 | * `UInt8Array` input values return the actual BN. `null` or `undefined` values returns an `0x0` value.
|
10 | * @param value The value to convert
|
11 | * @param options Options to pass while converting
|
12 | * @param options.isLe Convert using Little Endian (default)
|
13 | * @param options.isNegative Convert using two's complement
|
14 | * @example
|
15 | * <BR>
|
16 | *
|
17 | * ```javascript
|
18 | * import { u8aToBn } from '@polkadot/util';
|
19 | *
|
20 | * u8aToHex(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0xf])); // 0x68656c0f
|
21 | * ```
|
22 | */
|
23 | function u8aToBn(value, { isLe = true, isNegative = false } = {}) {
|
24 | // slice + reverse is expensive, however SCALE is LE by default so this is the path
|
25 | // we are most interested in (the BE is added for the sake of being comprehensive)
|
26 | if (!isLe) {
|
27 | value = value.slice().reverse();
|
28 | }
|
29 | const count = value.length;
|
30 | // shortcut for <= u48 values - in this case the manual conversion
|
31 | // here seems to be more efficient than passing the full array
|
32 | if (isNegative && count && (value[count - 1] & 0x80)) {
|
33 | // Most common case i{8, 16, 32} default LE SCALE-encoded
|
34 | // For <= 32, we also optimize the xor to a single op
|
35 | switch (count) {
|
36 | case 0:
|
37 | return new bn_js_1.BN(0);
|
38 | case 1:
|
39 | return new bn_js_1.BN(((value[0] ^ 255) * -1) - 1);
|
40 | case 2:
|
41 | return new bn_js_1.BN((((value[0] + (value[1] << 8)) ^ 65535) * -1) - 1);
|
42 | case 3:
|
43 | return new bn_js_1.BN((((value[0] + (value[1] << 8) + (value[2] << 16)) ^ 16777215) * -1) - 1);
|
44 | case 4:
|
45 | // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to
|
46 | // 32-bit, in the case where the top-most bit is set this yields a negative value
|
47 | return new bn_js_1.BN((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 16777216)) ^ 4294967295) * -1) - 1);
|
48 | case 5:
|
49 | return new bn_js_1.BN(((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 16777216)) ^ 4294967295) + ((value[4] ^ 0xff) * 4294967296)) * -1) - 1);
|
50 | case 6:
|
51 | return new bn_js_1.BN(((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 16777216)) ^ 4294967295) + (((value[4] + (value[5] << 8)) ^ 65535) * 4294967296)) * -1) - 1);
|
52 | default:
|
53 | return new bn_js_1.BN(value, 'le').fromTwos(count * 8);
|
54 | }
|
55 | }
|
56 | // Most common case - u{8, 16, 32} default LE SCALE-encoded
|
57 | //
|
58 | // There are some slight benefits in unrolling this specific loop,
|
59 | // however it comes with diminishing returns since here the actual
|
60 | // `new BN` does seem to take up the bulk of the time
|
61 | switch (count) {
|
62 | case 0:
|
63 | return new bn_js_1.BN(0);
|
64 | case 1:
|
65 | return new bn_js_1.BN(value[0]);
|
66 | case 2:
|
67 | return new bn_js_1.BN(value[0] + (value[1] << 8));
|
68 | case 3:
|
69 | return new bn_js_1.BN(value[0] + (value[1] << 8) + (value[2] << 16));
|
70 | case 4:
|
71 | // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to
|
72 | // 32-bit, in the case where the top-most bit is set this yields a negative value
|
73 | return new bn_js_1.BN(value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 16777216));
|
74 | case 5:
|
75 | return new bn_js_1.BN(value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8)) * 16777216));
|
76 | case 6:
|
77 | return new bn_js_1.BN(value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8) + (value[5] << 16)) * 16777216));
|
78 | default:
|
79 | return new bn_js_1.BN(value, 'le');
|
80 | }
|
81 | }
|
82 | exports.u8aToBn = u8aToBn;
|