move vanillae ts over here
This commit is contained in:
@@ -0,0 +1,418 @@
|
||||
/**
|
||||
* Base58 encoding/decoding
|
||||
*/
|
||||
|
||||
export {
|
||||
encode,
|
||||
decode
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// ENCODING
|
||||
//=============================================================================
|
||||
|
||||
/**
|
||||
* Encode a Uint8Array into base58
|
||||
*/
|
||||
function
|
||||
encode
|
||||
(binary : Uint8Array)
|
||||
: string
|
||||
{
|
||||
let num_leading_zeros : number = nlz(binary);
|
||||
let rest : Uint8Array = binary.slice(num_leading_zeros);
|
||||
let ones : string = encode_zeros(num_leading_zeros);
|
||||
let rest_b58 : string = encode_rest(rest);
|
||||
let result : string = ones + rest_b58;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* count the number of leading zeros in a uint8array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function
|
||||
nlz
|
||||
(bytes: Uint8Array)
|
||||
: number
|
||||
{
|
||||
let n = 0;
|
||||
for (let this_byte of bytes)
|
||||
{
|
||||
if (0 === this_byte) { n++; }
|
||||
else { break; }
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generate a bunch of '1's for however many leading zeros there are
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function
|
||||
encode_zeros
|
||||
(how_many : number)
|
||||
: string
|
||||
{
|
||||
let ones : string = '';
|
||||
for (let i = 1;
|
||||
i <= how_many;
|
||||
i++)
|
||||
{
|
||||
ones += '1';
|
||||
}
|
||||
|
||||
return ones;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Encode a Uint8Array that has no leading zeros
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function
|
||||
encode_rest
|
||||
(bytes : Uint8Array)
|
||||
: string
|
||||
{
|
||||
let bytes_bignum : bigint = bytes_to_bigint(bytes);
|
||||
let result : string = bignum_to_base58(bytes_bignum);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convert a bytestring to a bignum
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function
|
||||
bytes_to_bigint
|
||||
(bytes: Uint8Array)
|
||||
: bigint
|
||||
{
|
||||
let acc_bigint : bigint = 0n;
|
||||
for(let this_byte of bytes)
|
||||
{
|
||||
acc_bigint <<= 8n;
|
||||
acc_bigint += BigInt(this_byte);
|
||||
}
|
||||
return acc_bigint;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convert a BigInt to Base58
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function
|
||||
bignum_to_base58
|
||||
(q: bigint)
|
||||
: string
|
||||
{
|
||||
let s = '';
|
||||
while (q !== 0n)
|
||||
{
|
||||
let this_n : bigint = q % 58n;
|
||||
q /= 58n;
|
||||
|
||||
let this_b58_char : string = bigint_to_char(this_n);
|
||||
s = this_b58_char + s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// DECODING
|
||||
//=============================================================================
|
||||
|
||||
/**
|
||||
* Decode a Base58 string into a Uint8Array
|
||||
*/
|
||||
function
|
||||
decode
|
||||
(base58: string)
|
||||
: Uint8Array
|
||||
{
|
||||
let num_leading_ones : number = nlo(base58);
|
||||
let rest : string = base58.slice(num_leading_ones);
|
||||
let zeros : Array<number> = decode_ones(num_leading_ones);
|
||||
let rest_arr : Array<number> = decode_rest(rest);
|
||||
let pre_result : Array<number> = zeros.concat(rest_arr);
|
||||
return new Uint8Array(pre_result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* count the number of leading 1 characters in a uint8array
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function
|
||||
nlo
|
||||
(base58: string)
|
||||
: number
|
||||
{
|
||||
let n = 0;
|
||||
for (let this_char of base58)
|
||||
{
|
||||
if ('1' === this_char) { n++; }
|
||||
else { break; }
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generate a bunch of '0's for however many leading ones there are
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function
|
||||
decode_ones
|
||||
(how_many : number)
|
||||
: Array<number>
|
||||
{
|
||||
let zeros : Array<number> = [];
|
||||
for (let i = 1;
|
||||
i <= how_many;
|
||||
i++)
|
||||
{
|
||||
zeros.push(0);
|
||||
}
|
||||
|
||||
return zeros;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Decode a string that has no leading 1s
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function
|
||||
decode_rest
|
||||
(base58: string)
|
||||
: Array<number>
|
||||
{
|
||||
let result_bignum : bigint = base58_to_bigint(base58);
|
||||
let result : Array<number> = bigint_to_base256(result_bignum);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convert a base58 string to a bignum
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function
|
||||
base58_to_bigint
|
||||
(base58: string)
|
||||
: bigint
|
||||
{
|
||||
let acc_bigint : bigint = 0n;
|
||||
for(let this_char of base58)
|
||||
{
|
||||
acc_bigint *= 58n;
|
||||
acc_bigint += char_to_bigint(this_char);
|
||||
}
|
||||
return acc_bigint;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* convert a bignum into a byte array
|
||||
*
|
||||
* @end
|
||||
*/
|
||||
function
|
||||
bigint_to_base256
|
||||
(q: bigint)
|
||||
: Array<number>
|
||||
{
|
||||
let arr_reverse = [];
|
||||
while(q !== 0n)
|
||||
{
|
||||
let r: number = Number(q % 256n);
|
||||
q /= 256n;
|
||||
arr_reverse.push(r);
|
||||
}
|
||||
arr_reverse.reverse();
|
||||
return arr_reverse;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// TRANSLATION TABLES
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/**
|
||||
* Base58 integer -> character conversion table
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function
|
||||
bigint_to_char
|
||||
(n: bigint)
|
||||
: string
|
||||
{
|
||||
switch(n) {
|
||||
case 0n: return '1';
|
||||
case 1n: return '2';
|
||||
case 2n: return '3';
|
||||
case 3n: return '4';
|
||||
case 4n: return '5';
|
||||
case 5n: return '6';
|
||||
case 6n: return '7';
|
||||
case 7n: return '8';
|
||||
case 8n: return '9';
|
||||
case 9n: return 'A';
|
||||
case 10n: return 'B';
|
||||
case 11n: return 'C';
|
||||
case 12n: return 'D';
|
||||
case 13n: return 'E';
|
||||
case 14n: return 'F';
|
||||
case 15n: return 'G';
|
||||
case 16n: return 'H';
|
||||
case 17n: return 'J';
|
||||
case 18n: return 'K';
|
||||
case 19n: return 'L';
|
||||
case 20n: return 'M';
|
||||
case 21n: return 'N';
|
||||
case 22n: return 'P';
|
||||
case 23n: return 'Q';
|
||||
case 24n: return 'R';
|
||||
case 25n: return 'S';
|
||||
case 26n: return 'T';
|
||||
case 27n: return 'U';
|
||||
case 28n: return 'V';
|
||||
case 29n: return 'W';
|
||||
case 30n: return 'X';
|
||||
case 31n: return 'Y';
|
||||
case 32n: return 'Z';
|
||||
case 33n: return 'a';
|
||||
case 34n: return 'b';
|
||||
case 35n: return 'c';
|
||||
case 36n: return 'd';
|
||||
case 37n: return 'e';
|
||||
case 38n: return 'f';
|
||||
case 39n: return 'g';
|
||||
case 40n: return 'h';
|
||||
case 41n: return 'i';
|
||||
case 42n: return 'j';
|
||||
case 43n: return 'k';
|
||||
case 44n: return 'm';
|
||||
case 45n: return 'n';
|
||||
case 46n: return 'o';
|
||||
case 47n: return 'p';
|
||||
case 48n: return 'q';
|
||||
case 49n: return 'r';
|
||||
case 50n: return 's';
|
||||
case 51n: return 't';
|
||||
case 52n: return 'u';
|
||||
case 53n: return 'v';
|
||||
case 54n: return 'w';
|
||||
case 55n: return 'x';
|
||||
case 56n: return 'y';
|
||||
case 57n: return 'z';
|
||||
default:
|
||||
throw new Error('invalid base58 bigint: ' + n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base58 character -> integer conversion table
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function
|
||||
char_to_bigint
|
||||
(s: string)
|
||||
: bigint
|
||||
{
|
||||
switch(s) {
|
||||
case '1': return 0n;
|
||||
case '2': return 1n;
|
||||
case '3': return 2n;
|
||||
case '4': return 3n;
|
||||
case '5': return 4n;
|
||||
case '6': return 5n;
|
||||
case '7': return 6n;
|
||||
case '8': return 7n;
|
||||
case '9': return 8n;
|
||||
case 'A': return 9n;
|
||||
case 'B': return 10n;
|
||||
case 'C': return 11n;
|
||||
case 'D': return 12n;
|
||||
case 'E': return 13n;
|
||||
case 'F': return 14n;
|
||||
case 'G': return 15n;
|
||||
case 'H': return 16n;
|
||||
case 'J': return 17n;
|
||||
case 'K': return 18n;
|
||||
case 'L': return 19n;
|
||||
case 'M': return 20n;
|
||||
case 'N': return 21n;
|
||||
case 'P': return 22n;
|
||||
case 'Q': return 23n;
|
||||
case 'R': return 24n;
|
||||
case 'S': return 25n;
|
||||
case 'T': return 26n;
|
||||
case 'U': return 27n;
|
||||
case 'V': return 28n;
|
||||
case 'W': return 29n;
|
||||
case 'X': return 30n;
|
||||
case 'Y': return 31n;
|
||||
case 'Z': return 32n;
|
||||
case 'a': return 33n;
|
||||
case 'b': return 34n;
|
||||
case 'c': return 35n;
|
||||
case 'd': return 36n;
|
||||
case 'e': return 37n;
|
||||
case 'f': return 38n;
|
||||
case 'g': return 39n;
|
||||
case 'h': return 40n;
|
||||
case 'i': return 41n;
|
||||
case 'j': return 42n;
|
||||
case 'k': return 43n;
|
||||
case 'm': return 44n;
|
||||
case 'n': return 45n;
|
||||
case 'o': return 46n;
|
||||
case 'p': return 47n;
|
||||
case 'q': return 48n;
|
||||
case 'r': return 49n;
|
||||
case 's': return 50n;
|
||||
case 't': return 51n;
|
||||
case 'u': return 52n;
|
||||
case 'v': return 53n;
|
||||
case 'w': return 54n;
|
||||
case 'x': return 55n;
|
||||
case 'y': return 56n;
|
||||
case 'z': return 57n;
|
||||
default:
|
||||
throw new Error('invalid base58 char: ' + s);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user