diff options
Diffstat (limited to 'libs/base-x/ts_src')
-rw-r--r-- | libs/base-x/ts_src/index.ts | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/libs/base-x/ts_src/index.ts b/libs/base-x/ts_src/index.ts new file mode 100644 index 0000000..2fbedf5 --- /dev/null +++ b/libs/base-x/ts_src/index.ts | |||
@@ -0,0 +1,161 @@ | |||
1 | // base-x encoding / decoding | ||
2 | // Copyright (c) 2018 base-x contributors | ||
3 | // Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp) | ||
4 | // Distributed under the MIT software license, see the accompanying | ||
5 | // file LICENSE or http://www.opensource.org/licenses/mit-license.php. | ||
6 | |||
7 | // @ts-ignore | ||
8 | const _Buffer = require('safe-buffer').Buffer; | ||
9 | |||
10 | function base (ALPHABET: string): base.BaseConverter { | ||
11 | if (ALPHABET.length >= 255) throw new TypeError('Alphabet too long') | ||
12 | |||
13 | const BASE_MAP = new Uint8Array(256) | ||
14 | BASE_MAP.fill(255) | ||
15 | |||
16 | for (let i = 0; i < ALPHABET.length; i++) { | ||
17 | const x = ALPHABET.charAt(i) | ||
18 | const xc = x.charCodeAt(0) | ||
19 | |||
20 | if (BASE_MAP[xc] !== 255) throw new TypeError(x + ' is ambiguous') | ||
21 | BASE_MAP[xc] = i | ||
22 | } | ||
23 | |||
24 | const BASE = ALPHABET.length | ||
25 | const LEADER = ALPHABET.charAt(0) | ||
26 | const FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up | ||
27 | const iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up | ||
28 | |||
29 | function encode (source: Buffer): string { | ||
30 | if (!_Buffer.isBuffer(source)) throw new TypeError('Expected Buffer') | ||
31 | if (source.length === 0) return '' | ||
32 | |||
33 | // Skip & count leading zeroes. | ||
34 | let zeroes = 0 | ||
35 | let length = 0 | ||
36 | let pbegin = 0 | ||
37 | const pend = source.length | ||
38 | |||
39 | while (pbegin !== pend && source[pbegin] === 0) { | ||
40 | pbegin++ | ||
41 | zeroes++ | ||
42 | } | ||
43 | |||
44 | // Allocate enough space in big-endian base58 representation. | ||
45 | const size = ((pend - pbegin) * iFACTOR + 1) >>> 0 | ||
46 | const b58 = new Uint8Array(size) | ||
47 | |||
48 | // Process the bytes. | ||
49 | while (pbegin !== pend) { | ||
50 | let carry = source[pbegin] | ||
51 | |||
52 | // Apply "b58 = b58 * 256 + ch". | ||
53 | let i = 0 | ||
54 | for (let it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) { | ||
55 | carry += (256 * b58[it1]) >>> 0 | ||
56 | b58[it1] = (carry % BASE) >>> 0 | ||
57 | carry = (carry / BASE) >>> 0 | ||
58 | } | ||
59 | |||
60 | if (carry !== 0) throw new Error('Non-zero carry') | ||
61 | length = i | ||
62 | pbegin++ | ||
63 | } | ||
64 | |||
65 | // Skip leading zeroes in base58 result. | ||
66 | let it2 = size - length | ||
67 | while (it2 !== size && b58[it2] === 0) { | ||
68 | it2++ | ||
69 | } | ||
70 | |||
71 | // Translate the result into a string. | ||
72 | let str = LEADER.repeat(zeroes) | ||
73 | for (; it2 < size; ++it2) str += ALPHABET.charAt(b58[it2]) | ||
74 | |||
75 | return str | ||
76 | } | ||
77 | |||
78 | function decodeUnsafe (source: string): Buffer | undefined { | ||
79 | if (typeof source !== 'string') throw new TypeError('Expected String') | ||
80 | if (source.length === 0) return _Buffer.alloc(0) | ||
81 | |||
82 | let psz = 0 | ||
83 | |||
84 | // Skip leading spaces. | ||
85 | if (source[psz] === ' ') return | ||
86 | |||
87 | // Skip and count leading '1's. | ||
88 | let zeroes = 0 | ||
89 | let length = 0 | ||
90 | while (source[psz] === LEADER) { | ||
91 | zeroes++ | ||
92 | psz++ | ||
93 | } | ||
94 | |||
95 | // Allocate enough space in big-endian base256 representation. | ||
96 | const size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up. | ||
97 | const b256 = new Uint8Array(size) | ||
98 | |||
99 | // Process the characters. | ||
100 | while (source[psz]) { | ||
101 | // Decode character | ||
102 | let carry = BASE_MAP[source.charCodeAt(psz)] | ||
103 | |||
104 | // Invalid character | ||
105 | if (carry === 255) return | ||
106 | |||
107 | let i = 0 | ||
108 | for (let it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) { | ||
109 | carry += (BASE * b256[it3]) >>> 0 | ||
110 | b256[it3] = (carry % 256) >>> 0 | ||
111 | carry = (carry / 256) >>> 0 | ||
112 | } | ||
113 | |||
114 | if (carry !== 0) throw new Error('Non-zero carry') | ||
115 | length = i | ||
116 | psz++ | ||
117 | } | ||
118 | |||
119 | // Skip trailing spaces. | ||
120 | if (source[psz] === ' ') return | ||
121 | |||
122 | // Skip leading zeroes in b256. | ||
123 | let it4 = size - length | ||
124 | while (it4 !== size && b256[it4] === 0) { | ||
125 | it4++ | ||
126 | } | ||
127 | |||
128 | const vch = _Buffer.allocUnsafe(zeroes + (size - it4)) | ||
129 | vch.fill(0x00, 0, zeroes) | ||
130 | |||
131 | let j = zeroes | ||
132 | while (it4 !== size) { | ||
133 | vch[j++] = b256[it4++] | ||
134 | } | ||
135 | |||
136 | return vch | ||
137 | } | ||
138 | |||
139 | function decode (string: string): Buffer { | ||
140 | const buffer = decodeUnsafe(string) | ||
141 | if (buffer) return buffer | ||
142 | |||
143 | throw new Error('Non-base' + BASE + ' character') | ||
144 | } | ||
145 | |||
146 | return { | ||
147 | encode: encode, | ||
148 | decodeUnsafe: decodeUnsafe, | ||
149 | decode: decode | ||
150 | } | ||
151 | } | ||
152 | |||
153 | export = base; | ||
154 | |||
155 | declare namespace base { | ||
156 | interface BaseConverter { | ||
157 | encode(buffer: Buffer): string; | ||
158 | decodeUnsafe(string: string): Buffer | undefined; | ||
159 | decode(string: string): Buffer; | ||
160 | } | ||
161 | } | ||