UNPKG

2.94 kBJavaScriptView Raw
1/**
2 * @name u8aToNumber
3 * @summary Creates a number from a Uint8Array object.
4 */
5export function u8aToNumber(value, { isLe = true, isNegative = false } = {}) {
6 // slice + reverse is expensive, however SCALE is LE by default so this is the path
7 // we are most interested in (the BE is added for the sake of being comprehensive)
8 if (!isLe) {
9 value = value.slice().reverse();
10 }
11 const count = value.length;
12 // When the value is a i{8, 16, 24, 32, 40, 40} values and the top-most bit
13 // indicates a signed value, we use a two's complement conversion. If one of these
14 // flags are not set, we just do a normal unsigned conversion (the same shortcut
15 // applies in both the u8aTo{BigInt, Bn} conversions as well)
16 if (isNegative && count && (value[count - 1] & 0x80)) {
17 switch (count) {
18 case 0:
19 return 0;
20 case 1:
21 return (((value[0] ^ 255) * -1) - 1);
22 case 2:
23 return ((((value[0] + (value[1] << 8)) ^ 65535) * -1) - 1);
24 case 3:
25 return ((((value[0] + (value[1] << 8) + (value[2] << 16)) ^ 16777215) * -1) - 1);
26 case 4:
27 // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to
28 // 32-bit, in the case where the top-most bit is set this yields a negative value
29 return ((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 16777216)) ^ 4294967295) * -1) - 1);
30 case 5:
31 return (((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 16777216)) ^ 4294967295) + ((value[4] ^ 0xff) * 4294967296)) * -1) - 1);
32 case 6:
33 return (((((value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 16777216)) ^ 4294967295) + (((value[4] + (value[5] << 8)) ^ 65535) * 4294967296)) * -1) - 1);
34 default:
35 throw new Error('Value more than 48-bits cannot be reliably converted');
36 }
37 }
38 switch (count) {
39 case 0:
40 return 0;
41 case 1:
42 return value[0];
43 case 2:
44 return value[0] + (value[1] << 8);
45 case 3:
46 return value[0] + (value[1] << 8) + (value[2] << 16);
47 case 4:
48 // for the 3rd byte, we don't << 24 - since JS converts all bitwise operators to
49 // 32-bit, in the case where the top-most bit is set this yields a negative value
50 return value[0] + (value[1] << 8) + (value[2] << 16) + (value[3] * 16777216);
51 case 5:
52 return value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8)) * 16777216);
53 case 6:
54 return value[0] + (value[1] << 8) + (value[2] << 16) + ((value[3] + (value[4] << 8) + (value[5] << 16)) * 16777216);
55 default:
56 throw new Error('Value more than 48-bits cannot be reliably converted');
57 }
58}