137 lines
3.1 KiB
JavaScript
137 lines
3.1 KiB
JavaScript
|
/**
|
||
|
* Base64 operations.
|
||
|
*
|
||
|
* @author tlwr [toby@toby.codes]
|
||
|
* @copyright Crown Copyright 2017
|
||
|
* @license Apache-2.0
|
||
|
*
|
||
|
* @namespace
|
||
|
*/
|
||
|
var Base58 = {
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @constant
|
||
|
* @default
|
||
|
*/
|
||
|
ALPHABET_OPTIONS: [
|
||
|
{
|
||
|
name: "Bitcoin",
|
||
|
value: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
|
||
|
},
|
||
|
{
|
||
|
name: "Ripple",
|
||
|
value: "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz",
|
||
|
},
|
||
|
],
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @constant
|
||
|
* @default
|
||
|
*/
|
||
|
REMOVE_NON_ALPH_CHARS: true,
|
||
|
|
||
|
|
||
|
/**
|
||
|
* To Base58 operation.
|
||
|
*
|
||
|
* @param {byteArray} input
|
||
|
* @param {Object[]} args
|
||
|
* @returns {string}
|
||
|
*/
|
||
|
runTo: function(input, args) {
|
||
|
var alphabet = args[0] || Base58.ALPHABET_OPTIONS[0].value;
|
||
|
|
||
|
if (alphabet.length !== 58 ||
|
||
|
[].unique.call(alphabet).length !== 58) {
|
||
|
throw ("Error: alphabet must be of length 58");
|
||
|
}
|
||
|
|
||
|
if (input.length === 0) return "";
|
||
|
|
||
|
var result = [0];
|
||
|
|
||
|
input.forEach(function(b) {
|
||
|
var carry = (result[0] << 8) + b;
|
||
|
result[0] = carry % 58;
|
||
|
carry = (carry / 58) | 0;
|
||
|
|
||
|
for (var i = 1; i < result.length; i++) {
|
||
|
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("");
|
||
|
|
||
|
while (result.length < input.length) {
|
||
|
result = alphabet[0] + result;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
},
|
||
|
|
||
|
|
||
|
/**
|
||
|
* From Base58 operation.
|
||
|
*
|
||
|
* @param {string} input
|
||
|
* @param {Object[]} args
|
||
|
* @returns {byteArray}
|
||
|
*/
|
||
|
runFrom: function(input, args) {
|
||
|
var alphabet = args[0] || Base58.ALPHABET_OPTIONS[0].value;
|
||
|
|
||
|
if (alphabet.length !== 58 ||
|
||
|
[].unique.call(alphabet).length !== 58) {
|
||
|
throw ("Alphabet must be of length 58");
|
||
|
}
|
||
|
|
||
|
var removeNonAlphaChars = args[1];
|
||
|
if (removeNonAlphaChars === undefined)
|
||
|
removeNonAlphaChars = true;
|
||
|
|
||
|
if (input.length === 0) return [];
|
||
|
|
||
|
var result = [0];
|
||
|
|
||
|
[].forEach.call(input, function(c, charIndex) {
|
||
|
var index = alphabet.indexOf(c);
|
||
|
|
||
|
if (index === -1) {
|
||
|
if (removeNonAlphaChars) {
|
||
|
return;
|
||
|
} else {
|
||
|
throw ("Char " + c + " not in alphabet");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var carry = result[0] * 58 + index;
|
||
|
result[0] = carry & 0xFF;
|
||
|
carry = carry >> 8;
|
||
|
|
||
|
for (var i = 1; i < result.length; i++) {
|
||
|
carry += result[i] * 58;
|
||
|
result[i] = carry & 0xFF;
|
||
|
carry = carry >> 8;
|
||
|
}
|
||
|
|
||
|
while (carry > 0) {
|
||
|
result.push(carry & 0xFF);
|
||
|
carry = carry >> 8;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return result.reverse();
|
||
|
},
|
||
|
};
|