| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- // base-x encoding / decoding
- // based on https://github.com/cryptocoinjs/base-x 3.0.5
- // modification: removed Buffer dependency and node.modules entry
- // Copyright (c) 2018 base-x contributors
- // Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)
- // Distributed under the MIT software license, see the accompanying
- // file LICENSE or http://www.opensource.org/licenses/mit-license.php.
- (function(){
- 'use strict';
- this.baseX = function base (ALPHABET) {
- if (ALPHABET.length >= 255) throw new TypeError('Alphabet too long')
- const BASE_MAP = new Uint8Array(256)
- BASE_MAP.fill(255)
- for (let i = 0; i < ALPHABET.length; i++) {
- const x = ALPHABET.charAt(i)
- const xc = x.charCodeAt(0)
- if (BASE_MAP[xc] !== 255) throw new TypeError(x + ' is ambiguous')
- BASE_MAP[xc] = i
- }
- const BASE = ALPHABET.length
- const LEADER = ALPHABET.charAt(0)
- const FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up
- const iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up
- function encode (source) {
- if (source.length === 0) return ''
- // Skip & count leading zeroes.
- let zeroes = 0
- let length = 0
- let pbegin = 0
- const pend = source.length
- while (pbegin !== pend && source[pbegin] === 0) {
- pbegin++
- zeroes++
- }
- // Allocate enough space in big-endian base58 representation.
- const size = ((pend - pbegin) * iFACTOR + 1) >>> 0
- const b58 = new Uint8Array(size)
- // Process the bytes.
- while (pbegin !== pend) {
- let carry = source[pbegin]
- // Apply "b58 = b58 * 256 + ch".
- let i = 0
- for (let it = size - 1; (carry !== 0 || i < length) && (it !== -1); it--, i++) {
- carry += (256 * b58[it]) >>> 0
- b58[it] = (carry % BASE) >>> 0
- carry = (carry / BASE) >>> 0
- }
- if (carry !== 0) throw new Error('Non-zero carry')
- length = i
- pbegin++
- }
- // Skip leading zeroes in base58 result.
- let it = size - length
- while (it !== size && b58[it] === 0) {
- it++
- }
- // Translate the result into a string.
- let str = LEADER.repeat(zeroes)
- for (; it < size; ++it) str += ALPHABET.charAt(b58[it])
- return str
- }
- function decodeUnsafe (source) {
- if (typeof source !== 'string') throw new TypeError('Expected String')
- if (source.length === 0) return ''
- let psz = 0
- // Skip leading spaces.
- if (source[psz] === ' ') return
- // Skip and count leading '1's.
- let zeroes = 0
- let length = 0
- while (source[psz] === LEADER) {
- zeroes++
- psz++
- }
- // Allocate enough space in big-endian base256 representation.
- const size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up.
- const b256 = new Uint8Array(size)
- // Process the characters.
- while (source[psz]) {
- // Decode character
- let carry = BASE_MAP[source.charCodeAt(psz)]
- // Invalid character
- if (carry === 255) return
- let i = 0
- for (let it = size - 1; (carry !== 0 || i < length) && (it !== -1); it--, i++) {
- carry += (BASE * b256[it]) >>> 0
- b256[it] = (carry % 256) >>> 0
- carry = (carry / 256) >>> 0
- }
- if (carry !== 0) throw new Error('Non-zero carry')
- length = i
- psz++
- }
- // Skip trailing spaces.
- if (source[psz] === ' ') return
- // Skip leading zeroes in b256.
- let it = size - length
- while (it !== size && b256[it] === 0) {
- it++
- }
- var vch = [];
- let j = zeroes
- while (it !== size) {
- vch[j++] = b256[it++]
- }
- return vch
- }
- function decode (string) {
- const buffer = decodeUnsafe(string)
- if (buffer) return buffer
- throw new Error('Non-base' + BASE + ' character')
- }
- return {
- encode: encode,
- decodeUnsafe: decodeUnsafe,
- decode: decode
- }
- }
- }).call(this);
|