UNPKG

4.33 kBJavaScriptView Raw
1// Copyright 2017-2022 @polkadot/util authors & contributors
2// SPDX-License-Identifier: Apache-2.0
3import { BN } from "../bn/bn.js";
4import { isBoolean } from "../is/boolean.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
24/** @deprecated Use u8aToBn (value?: string | null, options?: ToBnOptions) */
25function u8aToBn(value, options = {}) {
26 // NOTE: This is the same process as followed in the hexToBn conversion
27 // For Uint8Array, default to LE
28 const {
29 isLe = true,
30 isNegative = false
31 } = isBoolean(options) ? {
32 isLe: options
33 } : options;
34 const count = value.length; // shortcut for <= u48 values - in this case the manual conversion
35 // here seems to be more efficient than passing the full array
36
37 if (count <= 6) {
38 if (isNegative) {
39 let result = 0;
40
41 if (isLe) {
42 // Most common case i{8, 16, 32} default LE SCALE-encoded
43 // For <= 32, we also optimize the xor to a single op
44 // (see the comments around unrolling in the next section)
45 switch (count) {
46 case 0:
47 return new BN(0);
48
49 case 1:
50 result = value[0] ^ 0x000000ff;
51 break;
52
53 case 2:
54 result = value[0] + (value[1] << 8) ^ 0x0000ffff;
55 break;
56
57 case 3:
58 result = value[0] + (value[1] << 8) + (value[2] << 16) ^ 0x00ffffff;
59 break;
60
61 case 4:
62 // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to
63 // 32-bit, in the case where the top-most bit is set this yields a negative value
64 result = value[0] + (value[1] << 8) + (value[2] << 16) + value[3] * 0x1000000 ^ 0xffffffff;
65 break;
66
67 case 5:
68 result = (value[0] + (value[1] << 8) + (value[2] << 16) + value[3] * 0x1000000 ^ 0xffffffff) + (value[4] ^ 0xff) * 0x100000000;
69 break;
70
71 default:
72 // 6
73 result = (value[0] + (value[1] << 8) + (value[2] << 16) + value[3] * 0x1000000 ^ 0xffffffff) + (value[4] + (value[5] << 8) ^ 0x0000ffff) * 0x100000000;
74 break;
75 }
76 } else {
77 for (let i = 0; i < count; i++) {
78 result = result * 0x100 + (value[i] ^ 0xff);
79 }
80 }
81
82 return count ? new BN(result * -1 - 1) : new BN(0);
83 } else if (isLe) {
84 // Most common case - u{8, 16, 32} default LE SCALE-encoded
85 //
86 // There are some slight benefits in unrolling this specific loop,
87 // however it comes with diminishing returns since here the actual
88 // `new BN` does seem to take up the bulk of the time
89 switch (count) {
90 case 0:
91 return new BN(0);
92
93 case 1:
94 return new BN(value[0]);
95
96 case 2:
97 return new BN(value[0] + (value[1] << 8));
98
99 case 3:
100 return new BN(value[0] + (value[1] << 8) + (value[2] << 16));
101
102 case 4:
103 // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to
104 // 32-bit, in the case where the top-most bit is set this yields a negative value
105 return new BN(value[0] + (value[1] << 8) + (value[2] << 16) + value[3] * 0x1000000);
106
107 case 5:
108 return new BN(value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] + (value[4] << 8)) * 0x1000000);
109
110 default:
111 // 6
112 return new BN(value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] + (value[4] << 8) + (value[5] << 16)) * 0x1000000);
113 }
114 } else {
115 let result = 0;
116
117 for (let i = 0; i < count; i++) {
118 result = result * 0x100 + value[i];
119 }
120
121 return new BN(result);
122 }
123 }
124
125 return isNegative ? new BN(value, isLe ? 'le' : 'be').fromTwos(value.length * 8) : new BN(value, isLe ? 'le' : 'be');
126}
127
128export { u8aToBn };
\No newline at end of file