From 22454ae842769fa819cde142b609d08e9db6be25 Mon Sep 17 00:00:00 2001 From: tcode2k16 Date: Mon, 17 Dec 2018 12:37:00 +0800 Subject: [PATCH] Add "To Base62" and "From Base62" operations --- src/core/config/Categories.json | 2 + src/core/operations/FromBase62.mjs | 52 ++++++++++++++++++++ src/core/operations/ToBase62.mjs | 54 ++++++++++++++++++++ test/index.mjs | 1 + test/tests/operations/Base62.mjs | 79 ++++++++++++++++++++++++++++++ 5 files changed, 188 insertions(+) create mode 100644 src/core/operations/FromBase62.mjs create mode 100644 src/core/operations/ToBase62.mjs create mode 100644 test/tests/operations/Base62.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index e9fe3399d..0a3a5f6e1 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -18,6 +18,8 @@ "From Binary", "To Octal", "From Octal", + "To Base62", + "From Base62", "To Base64", "From Base64", "Show Base64 offsets", diff --git a/src/core/operations/FromBase62.mjs b/src/core/operations/FromBase62.mjs new file mode 100644 index 000000000..5d56b3b75 --- /dev/null +++ b/src/core/operations/FromBase62.mjs @@ -0,0 +1,52 @@ +/** + * @author tcode2k16 [tcode2k16@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import BigNumber from "bignumber.js"; +import Utils from "../Utils"; + + +/** + * From Base62 operation + */ +class FromBase62 extends Operation { + + /** + * FromBase62 constructor + */ + constructor() { + super(); + + this.name = "From Base62"; + this.module = "Default"; + this.description = "decode base62 string"; + this.infoURL = "https://en.wikipedia.org/wiki/List_of_numeral_systems"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + if (input.length < 1) return ""; + const ALPHABET = Utils.expandAlphRange("0-9A-Za-z").join(""); + const BN = BigNumber.clone({ ALPHABET }); + + const re = new RegExp("[^" + ALPHABET.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g"); + input = input.replace(re, ""); + + const number = new BN(input, 62); + + return Utils.byteArrayToUtf8(Utils.convertToByteArray(number.toString(16), "Hex")); + } + +} + +export default FromBase62; diff --git a/src/core/operations/ToBase62.mjs b/src/core/operations/ToBase62.mjs new file mode 100644 index 000000000..a52679ef2 --- /dev/null +++ b/src/core/operations/ToBase62.mjs @@ -0,0 +1,54 @@ +/** + * @author tcode2k16 [tcode2k16@gmail.com] + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import Operation from "../Operation"; +import BigNumber from "bignumber.js"; +import Utils from "../Utils"; +import {toHexFast} from "../lib/Hex"; + +/** + * To Base62 operation + */ +class ToBase62 extends Operation { + + /** + * ToBase62 constructor + */ + constructor() { + super(); + + this.name = "To Base62"; + this.module = "Default"; + this.description = "encode string to base62"; + this.infoURL = "https://en.wikipedia.org/wiki/List_of_numeral_systems"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + if (input.length < 1) return ""; + + const ALPHABET = Utils.expandAlphRange("0-9A-Za-z").join(""); + const BN = BigNumber.clone({ ALPHABET }); + + input = Utils.strToByteArray(input); + input = toHexFast(input); + input = input.toUpperCase(); + + const number = new BN(input, 16); + + return number.toString(62); + } + +} + +export default ToBase62; diff --git a/test/index.mjs b/test/index.mjs index 9c11f6ae0..9b1caea1f 100644 --- a/test/index.mjs +++ b/test/index.mjs @@ -28,6 +28,7 @@ import "./tests/operations/BCD"; import "./tests/operations/BSON"; import "./tests/operations/Base58"; import "./tests/operations/Base64"; +import "./tests/operations/Base62"; import "./tests/operations/BitwiseOp"; import "./tests/operations/ByteRepr"; import "./tests/operations/CartesianProduct"; diff --git a/test/tests/operations/Base62.mjs b/test/tests/operations/Base62.mjs new file mode 100644 index 000000000..e96e4e46b --- /dev/null +++ b/test/tests/operations/Base62.mjs @@ -0,0 +1,79 @@ +/** + * Base62 tests. + * + * @author tcode2k16 [tcode2k16@gmail.com] + * + * @copyright Crown Copyright 2018 + * @license Apache-2.0 + */ + +import TestRegister from "../../TestRegister"; + +TestRegister.addTests([ + { + name: "To Base62: nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "To Base62", + args: [], + }, + ], + }, + { + name: "To Base62: Hello, World!", + input: "Hello, World!", + expectedOutput: "1wJfrzvdbtXUOlUjUf", + recipeConfig: [ + { + op: "To Base62", + args: [], + }, + ], + }, + { + name: "To Base62: UTF-8", + input: "ნუ პანიკას", + expectedOutput: "BPDNbjoGvDCDzHbKT77eWg0vGQrJuWRXltuRVZ", + recipeConfig: [ + { + op: "To Base62", + args: [], + }, + ], + }, + { + name: "From Base62: nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "From Base62", + args: [], + }, + ], + }, + { + name: "From Base62: Hello, World!", + input: "1wJfrzvdbtXUOlUjUf", + expectedOutput: "Hello, World!", + recipeConfig: [ + { + op: "From Base62", + args: [], + }, + ], + }, + { + name: "From Base62: UTF-8", + input: "BPDNbjoGvDCDzHbKT77eWg0vGQrJuWRXltuRVZ", + expectedOutput: "ნუ პანიკას", + recipeConfig: [ + { + op: "From Base62", + args: [], + }, + ], + } +]);