From e26e6a49613559801647df2aa9710308975ada10 Mon Sep 17 00:00:00 2001 From: toby Date: Fri, 10 Feb 2017 13:31:59 -0500 Subject: [PATCH 1/2] Add "To Base58" and "From Base58" operations --- src/js/config/Categories.js | 2 + src/js/config/OperationConfig.js | 31 +++++++ src/js/operations/Base58.js | 136 +++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100755 src/js/operations/Base58.js diff --git a/src/js/config/Categories.js b/src/js/config/Categories.js index 61e75568..aafa702a 100755 --- a/src/js/config/Categories.js +++ b/src/js/config/Categories.js @@ -40,6 +40,8 @@ var Categories = [ "Show Base64 offsets", "To Base32", "From Base32", + "To Base58", + "From Base58", "To Base", "From Base", "To HTML Entity", diff --git a/src/js/config/OperationConfig.js b/src/js/config/OperationConfig.js index ba406693..045f2832 100755 --- a/src/js/config/OperationConfig.js +++ b/src/js/config/OperationConfig.js @@ -164,6 +164,37 @@ var OperationConfig = { }, ] }, + "From Base58": { + description: "Base58 (similar to Base64) is a notation for encoding arbitrary byte data. It improves upon Base64 by removing easily misread characters (i.e. lI0O) to improve human readability.

This operation decodes data from an ASCII string (with an alphabet of your choosing, presets included) back into its raw form.

e.g. StV1DL6CwTryKyV becomes hello world

Base58 is commonly used in cryptocurrencies (Bitcoin, Ripple, etc).", + run: Base58.runFrom, + inputType: "string", + outputType: "byteArray", + args: [ + { + name: "Alphabet", + type: "editableOption", + value: Base58.ALPHABET_OPTIONS + }, + { + name: "Remove non‑alphabet chars", + type: "boolean", + value: Base58.REMOVE_NON_ALPH_CHARS + } + ] + }, + "To Base58": { + description: "Base58 (similar to Base64) is a notation for encoding arbitrary byte data. It improves upon Base64 by removing easily misread characters (i.e. lI0O) to improve human readability.

This operation encodes data in an ASCII string (with an alphabet of your choosing, presets included).

e.g. hello world becomes StV1DL6CwTryKyV

Base58 is commonly used in cryptocurrencies (Bitcoin, Ripple, etc).", + run: Base58.runTo, + inputType: "byteArray", + outputType: "string", + args: [ + { + name: "Alphabet", + type: "editableOption", + value: Base58.ALPHABET_OPTIONS + }, + ] + }, "From Base32": { description: "Base32 is a notation for encoding arbitrary byte data using a restricted set of symbols that can be conveniently used by humans and processed by computers. It uses a smaller set of characters than Base64, usually the uppercase alphabet and the numbers 2 to 7.", run: Base64.runFrom32, diff --git a/src/js/operations/Base58.js b/src/js/operations/Base58.js new file mode 100755 index 00000000..5799da4e --- /dev/null +++ b/src/js/operations/Base58.js @@ -0,0 +1,136 @@ +/** + * 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(); + }, +}; From 11e972ff26708dff9358e7f4172f7ae5a33c4640 Mon Sep 17 00:00:00 2001 From: toby Date: Fri, 10 Feb 2017 13:45:20 -0500 Subject: [PATCH 2/2] Change description in Base58.js --- src/js/operations/Base58.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/operations/Base58.js b/src/js/operations/Base58.js index 5799da4e..c76ce6ee 100755 --- a/src/js/operations/Base58.js +++ b/src/js/operations/Base58.js @@ -1,5 +1,5 @@ /** - * Base64 operations. + * Base58 operations. * * @author tlwr [toby@toby.codes] * @copyright Crown Copyright 2017