2018-05-16 16:25:05 +00:00
/**
* @author tlwr [toby@toby.codes]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
2019-07-09 12:23:59 +01:00
import Operation from "../Operation.mjs" ;
import Utils from "../Utils.mjs" ;
import OperationError from "../errors/OperationError.mjs" ;
import { ALPHABET_OPTIONS } from "../lib/Base58.mjs" ;
2018-05-16 16:25:05 +00:00
/**
* To Base58 operation
*/
class ToBase58 extends Operation {
/**
* ToBase58 constructor
*/
constructor () {
super ();
this . name = "To Base58" ;
this . module = "Default" ;
this . description = "Base58 (similar to Base64) is a notation for encoding arbitrary byte data. It differs from Base64 by removing easily misread characters (i.e. l, I, 0 and O) to improve human readability.<br><br>This operation encodes data in an ASCII string (with an alphabet of your choosing, presets included).<br><br>e.g. <code>hello world</code> becomes <code>StV1DL6CwTryKyV</code><br><br>Base58 is commonly used in cryptocurrencies (Bitcoin, Ripple, etc)." ;
2018-08-21 19:07:13 +01:00
this . infoURL = "https://wikipedia.org/wiki/Base58" ;
2019-07-29 17:09:46 +01:00
this . inputType = "ArrayBuffer" ;
2018-05-16 16:25:05 +00:00
this . outputType = "string" ;
this . args = [
{
"name" : "Alphabet" ,
"type" : "editableOption" ,
"value" : ALPHABET_OPTIONS
}
];
}
/**
2019-07-29 17:09:46 +01:00
* @param {ArrayBuffer} input
2018-05-16 16:25:05 +00:00
* @param {Object[]} args
* @returns {string}
*/
run ( input , args ) {
2019-07-29 17:09:46 +01:00
input = new Uint8Array ( input );
2018-05-16 16:25:05 +00:00
let alphabet = args [ 0 ] || ALPHABET_OPTIONS [ 0 ]. value ,
2024-04-01 17:31:36 +02:00
result = [];
2018-05-16 16:25:05 +00:00
alphabet = Utils . expandAlphRange ( alphabet ). join ( "" );
if ( alphabet . length !== 58 ||
[]. unique . call ( alphabet ). length !== 58 ) {
throw new OperationError ( "Error: alphabet must be of length 58" );
}
if ( input . length === 0 ) return "" ;
2018-10-21 21:10:49 -04:00
let zeroPrefix = 0 ;
for ( let i = 0 ; i < input . length && input [ i ] === 0 ; i ++ ) {
zeroPrefix ++ ;
}
2018-05-16 16:25:05 +00:00
input . forEach ( function ( b ) {
2024-04-01 17:31:36 +02:00
let carry = b ;
2018-05-16 16:25:05 +00:00
2024-04-01 17:31:36 +02:00
for ( let i = 0 ; i < result . length ; i ++ ) {
2018-05-16 16:25:05 +00:00
carry += result [ i ] << 8 ;
result [ i ] = carry % 58 ;
carry = ( carry / 58 ) | 0 ;
}
while ( carry > 0 ) {
result . push ( carry % 58 );
carry = ( carry / 58 ) | 0 ;
}
});
result = result . map ( function ( b ) {
return alphabet [ b ];
}). reverse (). join ( "" );
2018-10-21 21:10:49 -04:00
while ( zeroPrefix -- ) {
2018-05-16 16:25:05 +00:00
result = alphabet [ 0 ] + result ;
}
return result ;
}
}
export default ToBase58 ;