UNPKG

3.97 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.u8aToBn = void 0;
4const 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 */
23function 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}
82exports.u8aToBn = u8aToBn;