]> git.wincent.com - hextrapolate.git/blob - src/getDigits.js
fed0aa38439900d23800214978795a6f8d90e7c5
[hextrapolate.git] / src / getDigits.js
1 /**
2  * Copyright 2015-present Greg Hurrell. All rights reserved.
3  * Licensed under the terms of the MIT license.
4  *
5  * @flow
6  */
7
8 'use strict';
9
10 import DIGITS from './DIGITS';
11
12 /**
13  * Strips the leading prefix from `number` in `base` and returns the remaining
14  * part of the string.
15  *
16  * - "0x" (or "0X") for hexadecimal numbers.
17  * - "0" for octal numbers.
18  *
19  * For all bases, leading whitespace is stripped.
20  */
21 function stripPrefix(number: string, base: number): string {
22   if (base === 16) {
23     return number.replace(/^\s*0x/i, '');
24   } else if (base === 8) {
25     return number.replace(/^\s*0/, '');
26   } else {
27     return number.replace(/^\s*/, '');
28   }
29 }
30
31 function parse(digit: string, base: number) {
32   if (base > 36 && base <= 62) {
33     const position = DIGITS.indexOf(digit);
34     return position !== -1 && position < base ? position + 1 : NaN;
35   } else {
36     return parseInt(digit, base);
37   }
38 }
39
40 /**
41  * Breaks the string repsentation of `number` in `base` into an array of decimal
42  * digits (from least significant to most significant) for easier manipulation.
43  *
44  * For example, the hexadecimal representation `"40fa"` becomes `[10, 15, 0,
45  * 4]`.
46  */
47 export default function getDigits(number: string, base: number): Array<number> {
48   return stripPrefix(number, base).trim().split('').reverse().map(digit => {
49     const result = parse(digit, base);
50     if (isNaN(result)) {
51       throw new Error('Invalid digit `' + digit + '` for base `' + base + '`');
52     }
53     return result;
54   });
55 }