From 60340fc8ae0aafb31e28ee8586b23e35510cabbf Mon Sep 17 00:00:00 2001 From: n1474335 Date: Tue, 29 May 2018 01:20:44 +0100 Subject: [PATCH] ESM: Removed legacy files --- .eslintignore | 1 - src/core/config/scripts/portOperation.mjs | 4815 ----------------- src/core/operations/legacy/Arithmetic.js | 259 - src/core/operations/legacy/BCD.js | 215 - src/core/operations/legacy/BSON.js | 59 - src/core/operations/legacy/Base.js | 68 - src/core/operations/legacy/Base58.js | 137 - src/core/operations/legacy/ByteRepr.js | 355 -- src/core/operations/legacy/CharEnc.js | 97 - src/core/operations/legacy/Checksum.js | 179 - src/core/operations/legacy/Compress.js | 243 - src/core/operations/legacy/Convert.js | 413 -- src/core/operations/legacy/DateTime.js | 484 -- src/core/operations/legacy/Diff.js | 94 - src/core/operations/legacy/Endian.js | 100 - src/core/operations/legacy/Entropy.js | 195 - src/core/operations/legacy/FileType.js | 542 -- src/core/operations/legacy/Filetime.js | 103 - src/core/operations/legacy/HTML.js | 857 --- src/core/operations/legacy/HTTP.js | 158 - src/core/operations/legacy/Hash.js | 785 --- src/core/operations/legacy/Hexdump.js | 203 - src/core/operations/legacy/IP.js | 1086 ---- src/core/operations/legacy/MAC.js | 105 - src/core/operations/legacy/MS.js | 213 - src/core/operations/legacy/MorseCode.js | 190 - src/core/operations/legacy/NetBIOS.js | 70 - src/core/operations/legacy/Numberwang.js | 85 - src/core/operations/legacy/OS.js | 311 -- src/core/operations/legacy/OTP.js | 56 - src/core/operations/legacy/PHP.js | 160 - src/core/operations/legacy/PublicKey.js | 348 -- src/core/operations/legacy/Punycode.js | 58 - src/core/operations/legacy/QuotedPrintable.js | 272 - src/core/operations/legacy/Regex.js | 278 - src/core/operations/legacy/SeqUtils.js | 257 - src/core/operations/legacy/Shellcode.js | 96 - src/core/operations/legacy/StrUtils.js | 413 -- src/core/operations/legacy/Tidy.js | 250 - src/core/operations/legacy/ToTable.js | 164 - src/core/operations/legacy/UUID.js | 36 - src/core/operations/legacy/Unicode.js | 101 - src/core/operations/legacy/XKCD.js | 26 - src/web/App.js | 753 --- webpack.config.js | 4 +- 45 files changed, 2 insertions(+), 15692 deletions(-) delete mode 100644 src/core/config/scripts/portOperation.mjs delete mode 100644 src/core/operations/legacy/Arithmetic.js delete mode 100755 src/core/operations/legacy/BCD.js delete mode 100644 src/core/operations/legacy/BSON.js delete mode 100755 src/core/operations/legacy/Base.js delete mode 100755 src/core/operations/legacy/Base58.js delete mode 100755 src/core/operations/legacy/ByteRepr.js delete mode 100755 src/core/operations/legacy/CharEnc.js delete mode 100755 src/core/operations/legacy/Checksum.js delete mode 100755 src/core/operations/legacy/Compress.js delete mode 100755 src/core/operations/legacy/Convert.js delete mode 100755 src/core/operations/legacy/DateTime.js delete mode 100644 src/core/operations/legacy/Diff.js delete mode 100755 src/core/operations/legacy/Endian.js delete mode 100755 src/core/operations/legacy/Entropy.js delete mode 100755 src/core/operations/legacy/FileType.js delete mode 100644 src/core/operations/legacy/Filetime.js delete mode 100755 src/core/operations/legacy/HTML.js delete mode 100755 src/core/operations/legacy/HTTP.js delete mode 100755 src/core/operations/legacy/Hash.js delete mode 100755 src/core/operations/legacy/Hexdump.js delete mode 100755 src/core/operations/legacy/IP.js delete mode 100755 src/core/operations/legacy/MAC.js delete mode 100644 src/core/operations/legacy/MS.js delete mode 100644 src/core/operations/legacy/MorseCode.js delete mode 100644 src/core/operations/legacy/NetBIOS.js delete mode 100755 src/core/operations/legacy/Numberwang.js delete mode 100755 src/core/operations/legacy/OS.js delete mode 100755 src/core/operations/legacy/OTP.js delete mode 100644 src/core/operations/legacy/PHP.js delete mode 100755 src/core/operations/legacy/PublicKey.js delete mode 100755 src/core/operations/legacy/Punycode.js delete mode 100755 src/core/operations/legacy/QuotedPrintable.js delete mode 100644 src/core/operations/legacy/Regex.js delete mode 100755 src/core/operations/legacy/SeqUtils.js delete mode 100644 src/core/operations/legacy/Shellcode.js delete mode 100755 src/core/operations/legacy/StrUtils.js delete mode 100755 src/core/operations/legacy/Tidy.js delete mode 100644 src/core/operations/legacy/ToTable.js delete mode 100755 src/core/operations/legacy/UUID.js delete mode 100755 src/core/operations/legacy/Unicode.js delete mode 100755 src/core/operations/legacy/XKCD.js delete mode 100644 src/web/App.js diff --git a/.eslintignore b/.eslintignore index f7c44ebd..529676da 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1 @@ src/core/vendor/** -src/core/operations/legacy/** diff --git a/src/core/config/scripts/portOperation.mjs b/src/core/config/scripts/portOperation.mjs deleted file mode 100644 index cac7b1eb..00000000 --- a/src/core/config/scripts/portOperation.mjs +++ /dev/null @@ -1,4815 +0,0 @@ -/** - * Given an existing operation name, this script generates a skeleton for that op - * in the new ESM format. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2018 - * @license Apache-2.0 - */ - -/*eslint no-console: ["off"] */ - -import process from "process"; -import fs from "fs"; -import path from "path"; -import EscapeString from "../../operations/EscapeString"; - -if (process.argv.length < 4) { - console.log("Pass an operation name and legacy filename as arguments."); - console.log("Example> node --experimental-modules src/core/config/scripts/portOperation.mjs 'XOR' 'BitwiseOp'"); - process.exit(0); -} - -const dir = path.join(process.cwd() + "/src/core/config/"); -if (!fs.existsSync(dir)) { - console.log("\nCWD: " + process.cwd()); - console.log("Error: portOperation.mjs should be run from the project root"); - console.log("Example> node --experimental-modules src/core/config/scripts/portOperation.mjs"); - process.exit(1); -} - -/** - * Main function - */ -function main() { - const opName = process.argv[2]; - const legacyFilename = path.join(dir, `../operations/legacy/${process.argv[3]}.js`); - - if (!OP_CONFIG.hasOwnProperty(opName)) { - console.log(`${opName} cannot be found.`); - process.exit(0); - } - - const op = OP_CONFIG[opName]; - const moduleName = opName.replace(/\w\S*/g, txt => { - return txt.charAt(0).toUpperCase() + txt.substr(1); - }).replace(/[\s-/]/g, ""); - let legacyFile = ""; - - - // Read legacy file - try { - legacyFile = fs.readFileSync(legacyFilename, {encoding: "utf8"}); - } catch (err) { - console.log("Unable to read legacy file."); - console.log("Example> node --experimental-modules src/core/config/scripts/portOperation.mjs 'XOR' 'BitwiseOp'"); - process.exit(0); - } - - const author = legacyFile.match(/@author [^\n]+/)[0]; - const copyright = legacyFile.match(/@copyright [^\n]+/)[0]; - const utilsUsed = /Utils/.test(legacyFile); - const esc = new EscapeString(); - const desc = esc.run(op.description, ["Special chars", "Double"]); - const patterns = op.hasOwnProperty("patterns") ? ` - this.patterns = ${JSON.stringify(op.patterns, null, 4).split("\n").join("\n ")};` : ""; - - // Attempt to find the operation run function based on the JSDoc comment - const regex = `\\* ${opName} operation[^:]+:(?: function ?\\(input, args\\))? ?{([\\s\\S]+?)\n }`; - let runFunc = "\n"; - try { - runFunc = legacyFile.match(new RegExp(regex, "im"))[1]; - } catch (err) {} - - - // List all constants in legacyFile - const constants = []; - try { - const constantsRegex = /\* @constant[^/]+\/\s+([^\n]+)/gim; - let m; - - while ((m = constantsRegex.exec(legacyFile)) !== null) { - constants.push(m[1]); - } - } catch (err) {} - - const template = `/** - * ${author} - * ${copyright} - * @license Apache-2.0 - */ - -import Operation from "../Operation"; -${utilsUsed ? 'import Utils from "../Utils";\n' : ""} -/** - * ${opName} operation - */ -class ${moduleName} extends Operation { - - /** - * ${moduleName} constructor - */ - constructor() { - super(); - - this.name = "${opName}";${op.flowControl ? "\n this.flowControl = true;" : ""} - this.module = "${op.module}"; - this.description = "${desc}"; - this.inputType = "${op.inputType}"; - this.outputType = "${op.outputType}";${op.manualBake ? "\n this.manualBake = true;" : ""} - this.args = ${JSON.stringify(op.args, null, 4).split("\n").join("\n ")};${patterns} - } - - /** - * @param {${op.inputType}} input - * @param {Object[]} args - * @returns {${op.outputType}} - */ - run(input, args) {${runFunc} - } -${op.highlight ? ` - /** - * Highlight ${opName} - * - * @param {Object[]} pos - * @param {number} pos[].start - * @param {number} pos[].end - * @param {Object[]} args - * @returns {Object[]} pos - */ - highlight(pos, args) { - return pos; - } -` : ""}${op.highlightReverse ? ` - /** - * Highlight ${opName} in reverse - * - * @param {Object[]} pos - * @param {number} pos[].start - * @param {number} pos[].end - * @param {Object[]} args - * @returns {Object[]} pos - */ - highlightReverse(pos, args) { - return pos; - } -` : ""} -} - -export default ${moduleName}; -`; - - console.log("\nLegacy operation config\n-----------------------\n"); - console.log(JSON.stringify(op, null, 4)); - console.log("\n-----------------------\n"); - console.log("\nPotentially related constants\n-----------------------\n"); - console.log(constants.join("\n")); - console.log("\n-----------------------\n"); - - const filename = path.join(dir, `../operations/${moduleName}.mjs`); - if (fs.existsSync(filename)) { - console.log(`\x1b[31m\u274c ${filename} already exists. It has NOT been overwritten.\x1b[0m`); - process.exit(0); - } - fs.writeFileSync(filename, template); - - console.log("\x1b[32m\u2714\x1b[0m Operation written to \x1b[32m" + filename + "\x1b[0m"); - if (runFunc === "\n") { - console.log("\x1b[31m\u274c The run function could not be located automatically.\x1b[0m You will have to copy it accross manually."); - } else { - console.log("\x1b[32m\u2714\x1b[0m The run function was copied across. Double check that it was copied correctly. It may rely on other functions which have not been copied."); - } - console.log(`\nOpen \x1b[32m${legacyFilename}\x1b[0m and copy any relevant code over. Make sure you check imports, args and highlights. Code required by multiple operations should be stored in /src/core/lib/.\n\nDont't forget to run \x1b[36mgrunt lint\x1b[0m!`); -} - - -const OP_CONFIG = { - "Magic": { - module: "Default", - description: "The Magic operation attempts to detect various properties of the input data and suggests which operations could help to make more sense of it.

Options
Depth: If an operation appears to match the data, it will be run and the result will be analysed further. This argument controls the maximum number of levels of recursion.

Intensive mode: When this is turned on, various operations like XOR, bit rotates, and character encodings are brute-forced to attempt to detect valid data underneath. To improve performance, only the first 100 bytes of the data is brute-forced.

Extensive language support: At each stage, the relative byte frequencies of the data will be compared to average frequencies for a number of languages. The default set consists of ~40 of the most commonly used languages on the Internet. The extensive list consists of 284 languages and can result in many languages matching the data if their byte frequencies are similar.", - inputType: "ArrayBuffer", - outputType: "html", - flowControl: true, - args: [ - { - name: "Depth", - type: "number", - value: 3 - }, - { - name: "Intensive mode", - type: "boolean", - value: false - }, - { - name: "Extensive language support", - type: "boolean", - value: false - } - ] - }, - "Fork": { - module: "Default", - description: "Split the input data up based on the specified delimiter and run all subsequent operations on each branch separately.

For example, to decode multiple Base64 strings, enter them all on separate lines then add the 'Fork' and 'From Base64' operations to the recipe. Each string will be decoded separately.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "Split delimiter", - type: "binaryShortString", - value: "\\n" - }, - { - name: "Merge delimiter", - type: "binaryShortString", - value: "\\n" - }, - { - name: "Ignore errors", - type: "boolean", - value: false - } - ] - }, - "Merge": { - module: "Default", - description: "Consolidate all branches back into a single trunk. The opposite of Fork.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [] - }, - "Register": { - module: "Default", - description: "Extract data from the input and store it in registers which can then be passed into subsequent operations as arguments. Regular expression capture groups are used to select the data to extract.

To use registers in arguments, refer to them using the notation $Rn where n is the register number, starting at 0.

For example:
Input: Test
Extractor: (.*)
Argument: $R0 becomes Test

Registers can be escaped in arguments using a backslash. e.g. \\$R0 would become $R0 rather than Test.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "Extractor", - type: "binaryString", - value: "([\\s\\S]*)" - }, - { - name: "Case insensitive", - type: "boolean", - value: true - }, - { - name: "Multiline matching", - type: "boolean", - value: false - }, - ] - }, - "Jump": { - module: "Default", - description: "Jump forwards or backwards to the specified Label", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "Label name", - type: "string", - value: "" - }, - { - name: "Maximum jumps (if jumping backwards)", - type: "number", - value: 10 - } - ] - }, - "Conditional Jump": { - module: "Default", - description: "Conditionally jump forwards or backwards to the specified Label based on whether the data matches the specified regular expression.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "Match (regex)", - type: "string", - value: "" - }, - { - name: "Invert match", - type: "boolean", - value: false - }, - { - name: "Label name", - type: "shortString", - value: "" - }, - { - name: "Maximum jumps (if jumping backwards)", - type: "number", - value: 10 - } - ] - }, - "Label": { - module: "Default", - description: "Provides a location for conditional and fixed jumps to redirect execution to.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "Name", - type: "shortString", - value: "" - } - ] - }, - "Return": { - module: "Default", - description: "End execution of operations at this point in the recipe.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [] - }, - "Comment": { - module: "Default", - description: "Provides a place to write comments within the flow of the recipe. This operation has no computational effect.", - inputType: "string", - outputType: "string", - flowControl: true, - args: [ - { - name: "", - type: "text", - value: "" - } - ] - }, - "From Base64": { - module: "Default", - description: "Base64 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.

This operation decodes data from an ASCII Base64 string back into its raw format.

e.g. aGVsbG8= becomes hello", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Alphabet", - type: "editableOption", - value: "Base64.ALPHABET_OPTIONS" - }, - { - name: "Remove non-alphabet chars", - type: "boolean", - value: "Base64.REMOVE_NON_ALPH_CHARS" - } - ], - patterns: [ - { - match: "^(?:[A-Z\\d+/]{4})+(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?$", - flags: "i", - args: ["A-Za-z0-9+/=", false] - }, - { - match: "^[A-Z\\d\\-_]{20,}$", - flags: "i", - args: ["A-Za-z0-9-_", false] - }, - { - match: "^(?:[A-Z\\d+\\-]{4}){5,}(?:[A-Z\\d+\\-]{2}==|[A-Z\\d+\\-]{3}=)?$", - flags: "i", - args: ["A-Za-z0-9+\\-=", false] - }, - { - match: "^(?:[A-Z\\d./]{4}){5,}(?:[A-Z\\d./]{2}==|[A-Z\\d./]{3}=)?$", - flags: "i", - args: ["./0-9A-Za-z=", false] - }, - { - match: "^[A-Z\\d_.]{20,}$", - flags: "i", - args: ["A-Za-z0-9_.", false] - }, - { - match: "^(?:[A-Z\\d._]{4}){5,}(?:[A-Z\\d._]{2}--|[A-Z\\d._]{3}-)?$", - flags: "i", - args: ["A-Za-z0-9._-", false] - }, - { - match: "^(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?$", - flags: "i", - args: ["0-9a-zA-Z+/=", false] - }, - { - match: "^(?:[A-Z\\d+/]{4}){5,}(?:[A-Z\\d+/]{2}==|[A-Z\\d+/]{3}=)?$", - flags: "i", - args: ["0-9A-Za-z+/=", false] - }, - { - match: "^[ !\"#$%&'()*+,\\-./\\d:;<=>?@A-Z[\\\\\\]^_]{20,}$", - flags: "", - args: [" -_", false] - }, - { - match: "^[A-Z\\d+\\-]{20,}$", - flags: "i", - args: ["+\\-0-9A-Za-z", false] - }, - { - match: "^[!\"#$%&'()*+,\\-0-689@A-NP-VX-Z[`a-fh-mp-r]{20,}$", - flags: "", - args: ["!-,-0-689@A-NP-VX-Z[`a-fh-mp-r", false] - }, - { - match: "^(?:[N-ZA-M\\d+/]{4}){5,}(?:[N-ZA-M\\d+/]{2}==|[N-ZA-M\\d+/]{3}=)?$", - flags: "i", - args: ["N-ZA-Mn-za-m0-9+/=", false] - }, - { - match: "^[A-Z\\d./]{20,}$", - flags: "i", - args: ["./0-9A-Za-z", false] - }, - ] - }, - "To Base64": { - module: "Default", - description: "Base64 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.

This operation encodes data in an ASCII Base64 string.

e.g. hello becomes aGVsbG8=", - highlight: "func", - highlightReverse: "func", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Alphabet", - type: "editableOption", - value: "Base64.ALPHABET_OPTIONS" - }, - ] - }, - "From Base58": { - module: "Default", - 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.

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).", - 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" - } - ], - patterns: [ - { - match: "^[1-9A-HJ-NP-Za-km-z]{20,}$", - flags: "", - args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz", false] - }, - { - match: "^[1-9A-HJ-NP-Za-km-z]{20,}$", - flags: "", - args: ["rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz", false] - }, - ] - }, - "To Base58": { - module: "Default", - 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.

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).", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Alphabet", - type: "editableOption", - value: "Base58.ALPHABET_OPTIONS" - }, - ] - }, - "From Base32": { - module: "Default", - 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.", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Alphabet", - type: "binaryString", - value: "Base64.BASE32_ALPHABET" - }, - { - name: "Remove non-alphabet chars", - type: "boolean", - value: "Base64.REMOVE_NON_ALPH_CHARS" - } - ], - patterns: [ - { - match: "^(?:[A-Z2-7]{8})+(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}={1})?$", - flags: "", - args: ["A-Z2-7=", false] - }, - ] - }, - "To Base32": { - module: "Default", - 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.", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Alphabet", - type: "binaryString", - value: "Base64.BASE32_ALPHABET" - } - ] - }, - "Show Base64 offsets": { - module: "Default", - description: "When a string is within a block of data and the whole block is Base64'd, the string itself could be represented in Base64 in three distinct ways depending on its offset within the block.

This operation shows all possible offsets for a given string so that each possible encoding can be considered.", - inputType: "byteArray", - outputType: "html", - args: [ - { - name: "Alphabet", - type: "binaryString", - value: "Base64.ALPHABET" - }, - { - name: "Show variable chars and padding", - type: "boolean", - value: "Base64.OFFSETS_SHOW_VARIABLE" - } - ] - }, - "Disassemble x86": { - module: "Shellcode", - description: "Disassembly is the process of translating machine language into assembly language.

This operation supports 64-bit, 32-bit and 16-bit code written for Intel or AMD x86 processors. It is particularly useful for reverse engineering shellcode.

Input should be in hexadecimal.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Bit mode", - type: "option", - value: "Shellcode.MODE" - }, - { - name: "Compatibility", - type: "option", - value: "Shellcode.COMPATIBILITY" - }, - { - name: "Code Segment (CS)", - type: "number", - value: 16 - }, - { - name: "Offset (IP)", - type: "number", - value: 0 - }, - { - name: "Show instruction hex", - type: "boolean", - value: true - }, - { - name: "Show instruction position", - type: "boolean", - value: true - } - ] - }, - "XOR": { - module: "Default", - description: "XOR the input with the given key.
e.g. fe023da5

Options
Null preserving: If the current byte is 0x00 or the same as the key, skip it.

Scheme:", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "BitwiseOp.KEY_FORMAT" - }, - { - name: "Scheme", - type: "option", - value: "BitwiseOp.XOR_SCHEME" - }, - { - name: "Null preserving", - type: "boolean", - value: "BitwiseOp.XOR_PRESERVE_NULLS" - } - ] - }, - "XOR Brute Force": { - module: "Default", - description: "Enumerate all possible XOR solutions. Current maximum key length is 2 due to browser performance.

Optionally enter a string that you expect to find in the plaintext to filter results (crib).", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Key length", - type: "number", - value: "BitwiseOp.XOR_BRUTE_KEY_LENGTH" - }, - { - name: "Sample length", - type: "number", - value: "BitwiseOp.XOR_BRUTE_SAMPLE_LENGTH" - }, - { - name: "Sample offset", - type: "number", - value: "BitwiseOp.XOR_BRUTE_SAMPLE_OFFSET" - }, - { - name: "Scheme", - type: "option", - value: "BitwiseOp.XOR_SCHEME" - }, - { - name: "Null preserving", - type: "boolean", - value: "BitwiseOp.XOR_PRESERVE_NULLS" - }, - { - name: "Print key", - type: "boolean", - value: "BitwiseOp.XOR_BRUTE_PRINT_KEY" - }, - { - name: "Output as hex", - type: "boolean", - value: "BitwiseOp.XOR_BRUTE_OUTPUT_HEX" - }, - { - name: "Crib (known plaintext string)", - type: "binaryString", - value: "" - } - ] - }, - "NOT": { - module: "Default", - description: "Returns the inverse of each byte.", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [] - }, - "AND": { - module: "Default", - description: "AND the input with the given key.
e.g. fe023da5", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "BitwiseOp.KEY_FORMAT" - } - ] - }, - "OR": { - module: "Default", - description: "OR the input with the given key.
e.g. fe023da5", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "BitwiseOp.KEY_FORMAT" - } - ] - }, - "ADD": { - module: "Default", - description: "ADD the input with the given key (e.g. fe023da5), MOD 255", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "BitwiseOp.KEY_FORMAT" - } - ] - }, - "SUB": { - module: "Default", - description: "SUB the input with the given key (e.g. fe023da5), MOD 255", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "BitwiseOp.KEY_FORMAT" - } - ] - }, - "Sum": { - module: "Default", - description: "Adds together a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 18.5", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: "Arithmetic.DELIM_OPTIONS" - } - ] - }, - "Subtract": { - module: "Default", - description: "Subtracts a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 1.5", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: "Arithmetic.DELIM_OPTIONS" - } - ] - }, - "Multiply": { - module: "Default", - description: "Multiplies a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 40", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: "Arithmetic.DELIM_OPTIONS" - } - ] - }, - "Divide": { - module: "Default", - description: "Divides a list of numbers. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 2.5", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: "Arithmetic.DELIM_OPTIONS" - } - ] - }, - "Mean": { - module: "Default", - description: "Computes the mean (average) of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 .5 becomes 4.75", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: "Arithmetic.DELIM_OPTIONS" - } - ] - }, - "Median": { - module: "Default", - description: "Computes the median of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 1 .5 becomes 4.5", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: "Arithmetic.DELIM_OPTIONS" - } - ] - }, - "Standard Deviation": { - module: "Default", - description: "Computes the standard deviation of a number list. If an item in the string is not a number it is excluded from the list.

e.g. 0x0a 8 .5 becomes 4.089281382128433", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Delimiter", - type: "option", - value: "Arithmetic.DELIM_OPTIONS" - } - ] - }, - "To Table": { - module: "Default", - description: "Data can be split on different characters and rendered as an HTML or ASCII table with an optional header row.

Supports the CSV (Comma Separated Values) file format by default. Change the cell delimiter argument to \\t to support TSV (Tab Separated Values) or | for PSV (Pipe Separated Values).

You can enter as many delimiters as you like. Each character will be treat as a separate possible delimiter.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Cell delimiters", - type: "binaryShortString", - value: "," - }, - { - name: "Row delimiters", - type: "binaryShortString", - value: "\\n\\r" - }, - { - name: "Make first row header", - type: "boolean", - value: false - }, - { - name: "Format", - type: "option", - value: "ToTable.FORMATS" - } - ] - }, - "From Hex": { - module: "Default", - description: "Converts a hexadecimal byte string back into its raw value.

e.g. ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a becomes the UTF-8 encoded string Γειά σου", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Delimiter", - type: "option", - value: "ByteRepr.HEX_DELIM_OPTIONS" - } - ], - patterns: [ - { - match: "^(?:[\\dA-F]{2})+$", - flags: "i", - args: ["None"] - }, - { - match: "^[\\dA-F]{2}(?: [\\dA-F]{2})*$", - flags: "i", - args: ["Space"] - }, - { - match: "^[\\dA-F]{2}(?:,[\\dA-F]{2})*$", - flags: "i", - args: ["Comma"] - }, - { - match: "^[\\dA-F]{2}(?:;[\\dA-F]{2})*$", - flags: "i", - args: ["Semi-colon"] - }, - { - match: "^[\\dA-F]{2}(?::[\\dA-F]{2})*$", - flags: "i", - args: ["Colon"] - }, - { - match: "^[\\dA-F]{2}(?:\\n[\\dA-F]{2})*$", - flags: "i", - args: ["Line feed"] - }, - { - match: "^[\\dA-F]{2}(?:\\r\\n[\\dA-F]{2})*$", - flags: "i", - args: ["CRLF"] - }, - { - match: "^[\\dA-F]{2}(?:0x[\\dA-F]{2})*$", - flags: "i", - args: ["0x"] - }, - { - match: "^[\\dA-F]{2}(?:\\\\x[\\dA-F]{2})*$", - flags: "i", - args: ["\\x"] - } - ] - }, - "To Hex": { - module: "Default", - description: "Converts the input string to hexadecimal bytes separated by the specified delimiter.

e.g. The UTF-8 encoded string Γειά σου becomes ce 93 ce b5 ce b9 ce ac 20 cf 83 ce bf cf 85 0a", - highlight: "func", - highlightReverse: "func", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: "ByteRepr.HEX_DELIM_OPTIONS" - } - ] - }, - "From Octal": { - module: "Default", - description: "Converts an octal byte string back into its raw value.

e.g. 316 223 316 265 316 271 316 254 40 317 203 316 277 317 205 becomes the UTF-8 encoded string Γειά σου", - highlight: false, - highlightReverse: false, - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Delimiter", - type: "option", - value: "ByteRepr.DELIM_OPTIONS" - } - ], - patterns: [ - { - match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?: (?:[0-7]{1,2}|[123][0-7]{2}))*$", - flags: "", - args: ["Space"] - }, - { - match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:,(?:[0-7]{1,2}|[123][0-7]{2}))*$", - flags: "", - args: ["Comma"] - }, - { - match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:;(?:[0-7]{1,2}|[123][0-7]{2}))*$", - flags: "", - args: ["Semi-colon"] - }, - { - match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?::(?:[0-7]{1,2}|[123][0-7]{2}))*$", - flags: "", - args: ["Colon"] - }, - { - match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$", - flags: "", - args: ["Line feed"] - }, - { - match: "^(?:[0-7]{1,2}|[123][0-7]{2})(?:\\r\\n(?:[0-7]{1,2}|[123][0-7]{2}))*$", - flags: "", - args: ["CRLF"] - }, - ] - }, - "To Octal": { - module: "Default", - description: "Converts the input string to octal bytes separated by the specified delimiter.

e.g. The UTF-8 encoded string Γειά σου becomes 316 223 316 265 316 271 316 254 40 317 203 316 277 317 205", - highlight: false, - highlightReverse: false, - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: "ByteRepr.DELIM_OPTIONS" - } - ] - }, - "From Charcode": { - module: "Default", - description: "Converts unicode character codes back into text.

e.g. 0393 03b5 03b9 03ac 20 03c3 03bf 03c5 becomes Γειά σου", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Delimiter", - type: "option", - value: "ByteRepr.DELIM_OPTIONS" - }, - { - name: "Base", - type: "number", - value: "ByteRepr.CHARCODE_BASE" - } - ] - }, - "To Charcode": { - module: "Default", - description: "Converts text to its unicode character code equivalent.

e.g. Γειά σου becomes 0393 03b5 03b9 03ac 20 03c3 03bf 03c5", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: "ByteRepr.DELIM_OPTIONS" - }, - { - name: "Base", - type: "number", - value: "ByteRepr.CHARCODE_BASE" - } - ] - }, - "From Binary": { - module: "Default", - description: "Converts a binary string back into its raw form.

e.g. 01001000 01101001 becomes Hi", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Delimiter", - type: "option", - value: "ByteRepr.BIN_DELIM_OPTIONS" - } - ], - patterns: [ - { - match: "^(?:[01]{8})+$", - flags: "", - args: ["None"] - }, - { - match: "^(?:[01]{8})(?: [01]{8})*$", - flags: "", - args: ["Space"] - }, - { - match: "^(?:[01]{8})(?:,[01]{8})*$", - flags: "", - args: ["Comma"] - }, - { - match: "^(?:[01]{8})(?:;[01]{8})*$", - flags: "", - args: ["Semi-colon"] - }, - { - match: "^(?:[01]{8})(?::[01]{8})*$", - flags: "", - args: ["Colon"] - }, - { - match: "^(?:[01]{8})(?:\\n[01]{8})*$", - flags: "", - args: ["Line feed"] - }, - { - match: "^(?:[01]{8})(?:\\r\\n[01]{8})*$", - flags: "", - args: ["CRLF"] - }, - ] - }, - "To Binary": { - module: "Default", - description: "Displays the input data as a binary string.

e.g. Hi becomes 01001000 01101001", - highlight: "func", - highlightReverse: "func", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: "ByteRepr.BIN_DELIM_OPTIONS" - } - ] - }, - "From Decimal": { - module: "Default", - description: "Converts the data from an ordinal integer array back into its raw form.

e.g. 72 101 108 108 111 becomes Hello", - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Delimiter", - type: "option", - value: "ByteRepr.DELIM_OPTIONS" - } - ], - patterns: [ - { - match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?: (?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", - flags: "", - args: ["Space"] - }, - { - match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:,(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", - flags: "", - args: ["Comma"] - }, - { - match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:;(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", - flags: "", - args: ["Semi-colon"] - }, - { - match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?::(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", - flags: "", - args: ["Colon"] - }, - { - match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", - flags: "", - args: ["Line feed"] - }, - { - match: "^(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5])(?:\\r\\n(?:\\d{1,2}|1\\d{2}|2[0-4]\\d|25[0-5]))*$", - flags: "", - args: ["CRLF"] - }, - ] - }, - "To Decimal": { - module: "Default", - description: "Converts the input data to an ordinal integer array.

e.g. Hello becomes 72 101 108 108 111", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: "ByteRepr.DELIM_OPTIONS" - } - ] - }, - "From Hexdump": { - module: "Default", - description: "Attempts to convert a hexdump back into raw data. This operation supports many different hexdump variations, but probably not all. Make sure you verify that the data it gives you is correct before continuing analysis.", - highlight: "func", - highlightReverse: "func", - inputType: "string", - outputType: "byteArray", - args: [], - patterns: [ - { - match: "^(?:(?:[\\dA-F]{4,16}:?)?\\s*((?:[\\dA-F]{2}\\s){1,8}(?:\\s|[\\dA-F]{2}-)(?:[\\dA-F]{2}\\s){1,8}|(?:[\\dA-F]{2}\\s|[\\dA-F]{4}\\s)+)[^\\n]*\\n?)+$", - flags: "i", - args: [] - }, - ] - }, - "To Hexdump": { - module: "Default", - description: "Creates a hexdump of the input data, displaying both the hexadecimal values of each byte and an ASCII representation alongside.", - highlight: "func", - highlightReverse: "func", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Width", - type: "number", - value: "Hexdump.WIDTH" - }, - { - name: "Upper case hex", - type: "boolean", - value: "Hexdump.UPPER_CASE" - }, - { - name: "Include final length", - type: "boolean", - value: "Hexdump.INCLUDE_FINAL_LENGTH" - } - ] - }, - "From Base": { - module: "Default", - description: "Converts a number to decimal from a given numerical base.", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Radix", - type: "number", - value: "Base.DEFAULT_RADIX" - } - ] - }, - "To Base": { - module: "Default", - description: "Converts a decimal number to a given numerical base.", - inputType: "BigNumber", - outputType: "string", - args: [ - { - name: "Radix", - type: "number", - value: "Base.DEFAULT_RADIX" - } - ] - }, - "From HTML Entity": { - module: "Default", - description: "Converts HTML entities back to characters

e.g. &amp; becomes &", // tags required to stop the browser just printing & - inputType: "string", - outputType: "string", - args: [], - patterns: [ - { - match: "&(?:#\\d{2,3}|#x[\\da-f]{2}|[a-z]{2,6});", - flags: "i", - args: [] - }, - ] - }, - "To HTML Entity": { - module: "Default", - description: "Converts characters to HTML entities

e.g. & becomes &amp;", // tags required to stop the browser just printing & - inputType: "string", - outputType: "string", - args: [ - { - name: "Convert all characters", - type: "boolean", - value: "HTML.CONVERT_ALL" - }, - { - name: "Convert to", - type: "option", - value: "HTML.CONVERT_OPTIONS" - } - ] - }, - "Strip HTML tags": { - module: "Default", - description: "Removes all HTML tags from the input.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Remove indentation", - type: "boolean", - value: "HTML.REMOVE_INDENTATION" - }, - { - name: "Remove excess line breaks", - type: "boolean", - value: "HTML.REMOVE_LINE_BREAKS" - } - ] - }, - "URL Decode": { - module: "URL", - description: "Converts URI/URL percent-encoded characters back to their raw values.

e.g. %3d becomes =", - inputType: "string", - outputType: "string", - args: [], - patterns: [ - { - match: ".*(?:%[\\da-f]{2}.*){4}", - flags: "i", - args: [] - }, - ] - }, - "URL Encode": { - module: "URL", - description: "Encodes problematic characters into percent-encoding, a format supported by URIs/URLs.

e.g. = becomes %3d", - inputType: "string", - outputType: "string", - args: [ - { - name: "Encode all special chars", - type: "boolean", - value: "URL_.ENCODE_ALL" - } - ] - }, - "Parse URI": { - module: "URL", - description: "Pretty prints complicated Uniform Resource Identifier (URI) strings for ease of reading. Particularly useful for Uniform Resource Locators (URLs) with a lot of arguments.", - inputType: "string", - outputType: "string", - args: [] - }, - "Unescape Unicode Characters": { - module: "Default", - description: "Converts unicode-escaped character notation back into raw characters.

Supports the prefixes:
  • \\u
  • %u
  • U+
e.g. \\u03c3\\u03bf\\u03c5 becomes σου", - inputType: "string", - outputType: "string", - args: [ - { - name: "Prefix", - type: "option", - value: "Unicode.PREFIXES" - } - ] - }, - "Escape Unicode Characters": { - module: "Default", - description: "Converts characters to their unicode-escaped notations.

Supports the prefixes:
  • \\u
  • %u
  • U+
e.g. σου becomes \\u03C3\\u03BF\\u03C5", - inputType: "string", - outputType: "string", - args: [ - { - name: "Prefix", - type: "option", - value: "Unicode.PREFIXES" - }, - { - name: "Encode all chars", - type: "boolean", - value: false - }, - { - name: "Padding", - type: "number", - value: 4 - }, - { - name: "Uppercase hex", - type: "boolean", - value: true - } - ], - patterns: [ - { - match: "\\\\u(?:[\\da-f]{4,6})", - flags: "i", - args: ["\\u"] - }, - { - match: "%u(?:[\\da-f]{4,6})", - flags: "i", - args: ["%u"] - }, - { - match: "U\\+(?:[\\da-f]{4,6})", - flags: "i", - args: ["U+"] - }, - ] - }, - "From Quoted Printable": { - module: "Default", - description: "Converts QP-encoded text back to standard text.", - inputType: "string", - outputType: "byteArray", - args: [], - patterns: [ - { - match: "^[\\x21-\\x3d\\x3f-\\x7e \\t]*(?:=[\\da-f]{2}|=\\r?\\n)(?:[\\x21-\\x3d\\x3f-\\x7e \\t]|=[\\da-f]{2}|=\\r?\\n)*$", - flags: "i", - args: [] - }, - ] - }, - "To Quoted Printable": { - module: "Default", - description: "Quoted-Printable, or QP encoding, is an encoding using printable ASCII characters (alphanumeric and the equals sign '=') to transmit 8-bit data over a 7-bit data path or, generally, over a medium which is not 8-bit clean. It is defined as a MIME content transfer encoding for use in e-mail.

QP works by using the equals sign '=' as an escape character. It also limits line length to 76, as some software has limits on line length.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "From Punycode": { - module: "Encodings", - description: "Punycode is a way to represent Unicode with the limited character subset of ASCII supported by the Domain Name System.

e.g. mnchen-3ya decodes to münchen", - inputType: "string", - outputType: "string", - args: [ - { - name: "Internationalised domain name", - type: "boolean", - value: "Punycode.IDN" - } - ] - }, - "To Punycode": { - module: "Encodings", - description: "Punycode is a way to represent Unicode with the limited character subset of ASCII supported by the Domain Name System.

e.g. münchen encodes to mnchen-3ya", - inputType: "string", - outputType: "string", - args: [ - { - name: "Internationalised domain name", - type: "boolean", - value: "Punycode.IDN" - } - ] - }, - "From Hex Content": { - module: "Default", - description: "Translates hexadecimal bytes in text back to raw bytes.

e.g. foo|3d|bar becomes foo=bar.", - inputType: "string", - outputType: "byteArray", - args: [] - }, - "To Hex Content": { - module: "Default", - description: "Converts special characters in a string to hexadecimal.

e.g. foo=bar becomes foo|3d|bar.", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Convert", - type: "option", - value: "ByteRepr.HEX_CONTENT_CONVERT_WHICH" - }, - { - name: "Print spaces between bytes", - type: "boolean", - value: "ByteRepr.HEX_CONTENT_SPACES_BETWEEN_BYTES" - }, - ] - }, - "Change IP format": { - module: "JSBN", - description: "Convert an IP address from one format to another, e.g. 172.20.23.54 to ac141736", - inputType: "string", - outputType: "string", - args: [ - { - name: "Input format", - type: "option", - value: "IP.IP_FORMAT_LIST" - }, - { - name: "Output format", - type: "option", - value: "IP.IP_FORMAT_LIST" - } - ] - }, - "Parse IP range": { - module: "JSBN", - description: "Given a CIDR range (e.g. 10.0.0.0/24) or a hyphenated range (e.g. 10.0.0.0 - 10.0.1.0), this operation provides network information and enumerates all IP addresses in the range.

IPv6 is supported but will not be enumerated.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Include network info", - type: "boolean", - value: "IP.INCLUDE_NETWORK_INFO" - }, - { - name: "Enumerate IP addresses", - type: "boolean", - value: "IP.ENUMERATE_ADDRESSES" - }, - { - name: "Allow large queries", - type: "boolean", - value: "IP.ALLOW_LARGE_LIST" - } - ] - }, - "Group IP addresses": { - module: "JSBN", - description: "Groups a list of IP addresses into subnets. Supports both IPv4 and IPv6 addresses.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: "IP.DELIM_OPTIONS" - }, - { - name: "Subnet (CIDR)", - type: "number", - value: "IP.GROUP_CIDR" - }, - { - name: "Only show the subnets", - type: "boolean", - value: "IP.GROUP_ONLY_SUBNET" - } - ] - }, - "Parse IPv6 address": { - module: "JSBN", - description: "Displays the longhand and shorthand versions of a valid IPv6 address.

Recognises all reserved ranges and parses encapsulated or tunnelled addresses including Teredo and 6to4.", - inputType: "string", - outputType: "string", - args: [] - }, - "Parse IPv4 header": { - module: "JSBN", - description: "Given an IPv4 header, this operations parses and displays each field in an easily readable format.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Input format", - type: "option", - value: "IP.IP_HEADER_FORMAT" - } - ] - }, - "Encode text": { - module: "CharEnc", - description: [ - "Encodes text into the chosen character encoding.", - "

", - "Supported charsets are:", - "
    ", - 'TODO -----------------------Object.keys(CharEnc.IO_FORMAT).map(e => `
  • ${e}
  • `).join("\n")', - "
", - ].join("\n"), - inputType: "string", - outputType: "byteArray", - args: [ - { - name: "Encoding", - type: "option", - value: "Object.keys(CharEnc.IO_FORMAT)," - }, - ], - }, - "Decode text": { - module: "CharEnc", - description: [ - "Decodes text from the chosen character encoding.", - "

", - "Supported charsets are:", - "
    ", - 'TODO -----------------------Object.keys(CharEnc.IO_FORMAT).map(e => `
  • ${e}
  • `).join("\n")', - "
", - ].join("\n"), - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Encoding", - type: "option", - value: "Object.keys(CharEnc.IO_FORMAT)," - }, - ] - }, - "AES Decrypt": { - module: "Ciphers", - description: "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.

Key: The following algorithms will be used based on the size of the key:
  • 16 bytes = AES-128
  • 24 bytes = AES-192
  • 32 bytes = AES-256


IV: The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.

GCM Tag: This field is ignored unless 'GCM' mode is used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "Mode", - type: "option", - value: "Cipher.AES_MODES" - }, - { - name: "Input", - type: "option", - value: "Cipher.IO_FORMAT4" - }, - { - name: "Output", - type: "option", - value: "Cipher.IO_FORMAT3" - }, - { - name: "GCM Tag", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - ] - }, - "AES Encrypt": { - module: "Ciphers", - description: "Advanced Encryption Standard (AES) is a U.S. Federal Information Processing Standard (FIPS). It was selected after a 5-year process where 15 competing designs were evaluated.

Key: The following algorithms will be used based on the size of the key:
  • 16 bytes = AES-128
  • 24 bytes = AES-192
  • 32 bytes = AES-256
You can generate a password-based key using one of the KDF operations.

IV: The Initialization Vector should be 16 bytes long. If not entered, it will default to 16 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "Mode", - type: "option", - value: "Cipher.AES_MODES" - }, - { - name: "Input", - type: "option", - value: "Cipher.IO_FORMAT3" - }, - { - name: "Output", - type: "option", - value: "Cipher.IO_FORMAT4" - }, - ] - }, - "DES Decrypt": { - module: "Ciphers", - description: "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.

Key: DES uses a key length of 8 bytes (64 bits).
Triple DES uses a key length of 24 bytes (192 bits).

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "Mode", - type: "option", - value: "Cipher.DES_MODES" - }, - { - name: "Input", - type: "option", - value: "Cipher.IO_FORMAT4" - }, - { - name: "Output", - type: "option", - value: "Cipher.IO_FORMAT3" - }, - ] - }, - "DES Encrypt": { - module: "Ciphers", - description: "DES is a previously dominant algorithm for encryption, and was published as an official U.S. Federal Information Processing Standard (FIPS). It is now considered to be insecure due to its small key size.

Key: DES uses a key length of 8 bytes (64 bits).
Triple DES uses a key length of 24 bytes (192 bits).

You can generate a password-based key using one of the KDF operations.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "Mode", - type: "option", - value: "Cipher.DES_MODES" - }, - { - name: "Input", - type: "option", - value: "Cipher.IO_FORMAT3" - }, - { - name: "Output", - type: "option", - value: "Cipher.IO_FORMAT4" - }, - ] - }, - "Triple DES Decrypt": { - module: "Ciphers", - description: "Triple DES applies DES three times to each block to increase key size.

Key: Triple DES uses a key length of 24 bytes (192 bits).
DES uses a key length of 8 bytes (64 bits).

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "Mode", - type: "option", - value: "Cipher.DES_MODES" - }, - { - name: "Input", - type: "option", - value: "Cipher.IO_FORMAT4" - }, - { - name: "Output", - type: "option", - value: "Cipher.IO_FORMAT3" - }, - ] - }, - "Triple DES Encrypt": { - module: "Ciphers", - description: "Triple DES applies DES three times to each block to increase key size.

Key: Triple DES uses a key length of 24 bytes (192 bits).
DES uses a key length of 8 bytes (64 bits).

You can generate a password-based key using one of the KDF operations.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.

Padding: In CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "Mode", - type: "option", - value: "Cipher.DES_MODES" - }, - { - name: "Input", - type: "option", - value: "Cipher.IO_FORMAT3" - }, - { - name: "Output", - type: "option", - value: "Cipher.IO_FORMAT4" - }, - ] - }, - "Blowfish Decrypt": { - module: "Ciphers", - description: "Blowfish is a symmetric-key block cipher designed in 1993 by Bruce Schneier and included in a large number of cipher suites and encryption products. AES now receives more attention.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "Mode", - type: "option", - value: "Cipher.BLOWFISH_MODES" - }, - { - name: "Input", - type: "option", - value: "Cipher.BLOWFISH_OUTPUT_TYPES" - }, - { - name: "Output", - type: "option", - value: "Cipher.IO_FORMAT3" - }, - ] - }, - "Blowfish Encrypt": { - module: "Ciphers", - description: "Blowfish is a symmetric-key block cipher designed in 1993 by Bruce Schneier and included in a large number of cipher suites and encryption products. AES now receives more attention.

IV: The Initialization Vector should be 8 bytes long. If not entered, it will default to 8 null bytes.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "Mode", - type: "option", - value: "Cipher.BLOWFISH_MODES" - }, - { - name: "Input", - type: "option", - value: "Cipher.IO_FORMAT3" - }, - { - name: "Output", - type: "option", - value: "Cipher.BLOWFISH_OUTPUT_TYPES" - }, - ] - }, - "RC4": { - module: "Ciphers", - description: "RC4 (also known as ARC4) is a widely-used stream cipher designed by Ron Rivest. It is used in popular protocols such as SSL and WEP. Although remarkable for its simplicity and speed, the algorithm's history doesn't inspire confidence in its security.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Passphrase", - type: "toggleString", - value: "", - toggleValues: "Cipher.RC4_KEY_FORMAT" - }, - { - name: "Input format", - type: "option", - value: "Cipher.CJS_IO_FORMAT" - }, - { - name: "Output format", - type: "option", - value: "Cipher.CJS_IO_FORMAT" - }, - ] - }, - "RC4 Drop": { - module: "Ciphers", - description: "It was discovered that the first few bytes of the RC4 keystream are strongly non-random and leak information about the key. We can defend against this attack by discarding the initial portion of the keystream. This modified algorithm is traditionally called RC4-drop.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Passphrase", - type: "toggleString", - value: "", - toggleValues: "Cipher.RC4_KEY_FORMAT" - }, - { - name: "Input format", - type: "option", - value: "Cipher.CJS_IO_FORMAT" - }, - { - name: "Output format", - type: "option", - value: "Cipher.CJS_IO_FORMAT" - }, - { - name: "Number of bytes to drop", - type: "number", - value: "Cipher.RC4DROP_BYTES" - }, - ] - }, - "RC2 Decrypt": { - module: "Ciphers", - description: "RC2 (also known as ARC2) is a symmetric-key block cipher designed by Ron Rivest in 1987. 'RC' stands for 'Rivest Cipher'.

Key: RC2 uses a variable size key.

IV: To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.

Padding: In both CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "Input", - type: "option", - value: "Cipher.IO_FORMAT4" - }, - { - name: "Output", - type: "option", - value: "Cipher.IO_FORMAT3" - }, - ] - }, - "RC2 Encrypt": { - module: "Ciphers", - description: "RC2 (also known as ARC2) is a symmetric-key block cipher designed by Ron Rivest in 1987. 'RC' stands for 'Rivest Cipher'.

Key: RC2 uses a variable size key.

You can generate a password-based key using one of the KDF operations.

IV: To run the cipher in CBC mode, the Initialization Vector should be 8 bytes long. If the IV is left blank, the cipher will run in ECB mode.

Padding: In both CBC and ECB mode, PKCS#7 padding will be used.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "IV", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - { - name: "Input", - type: "option", - value: "Cipher.IO_FORMAT3" - }, - { - name: "Output", - type: "option", - value: "Cipher.IO_FORMAT4" - }, - ] - }, - "Pseudo-Random Number Generator": { - module: "Ciphers", - description: "A cryptographically-secure pseudo-random number generator (PRNG).

This operation uses the browser's built-in crypto.getRandomValues() method if available. If this cannot be found, it falls back to a Fortuna-based PRNG algorithm.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Number of bytes", - type: "number", - value: "Cipher.PRNG_BYTES" - }, - { - name: "Output as", - type: "option", - value: "Cipher.PRNG_OUTPUT" - } - ] - }, - "Derive PBKDF2 key": { - module: "Ciphers", - description: "PBKDF2 is a password-based key derivation function. It is part of RSA Laboratories' Public-Key Cryptography Standards (PKCS) series, specifically PKCS #5 v2.0, also published as Internet Engineering Task Force's RFC 2898.

In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can't be used directly as a cryptographic key, some processing is required.

A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack.

If you leave the salt argument empty, a random salt will be generated.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Passphrase", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT2" - }, - { - name: "Key size", - type: "number", - value: "Cipher.KDF_KEY_SIZE" - }, - { - name: "Iterations", - type: "number", - value: "Cipher.KDF_ITERATIONS" - }, - { - name: "Hashing function", - type: "option", - value: "Cipher.HASHERS" - }, - { - name: "Salt", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - ] - }, - "Derive EVP key": { - module: "Ciphers", - description: "EVP is a password-based key derivation function (PBKDF) used extensively in OpenSSL. In many applications of cryptography, user security is ultimately dependent on a password, and because a password usually can't be used directly as a cryptographic key, some processing is required.

A salt provides a large set of keys for any given password, and an iteration count increases the cost of producing keys from a password, thereby also increasing the difficulty of attack.

If you leave the salt argument empty, a random salt will be generated.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Passphrase", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT2" - }, - { - name: "Key size", - type: "number", - value: "Cipher.KDF_KEY_SIZE" - }, - { - name: "Iterations", - type: "number", - value: "Cipher.KDF_ITERATIONS" - }, - { - name: "Hashing function", - type: "option", - value: "Cipher.HASHERS" - }, - { - name: "Salt", - type: "toggleString", - value: "", - toggleValues: "Cipher.IO_FORMAT1" - }, - ] - }, - "Vigenère Encode": { - module: "Ciphers", - description: "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "string", - value: "" - } - ] - }, - "Vigenère Decode": { - module: "Ciphers", - description: "The Vigenere cipher is a method of encrypting alphabetic text by using a series of different Caesar ciphers based on the letters of a keyword. It is a simple form of polyalphabetic substitution.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Key", - type: "string", - value: "" - } - ] - }, - "Bifid Cipher Encode": { - module: "Ciphers", - description: "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Keyword", - type: "string", - value: "" - } - ] - }, - "Bifid Cipher Decode": { - module: "Ciphers", - description: "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Keyword", - type: "string", - value: "" - } - ] - }, - "Affine Cipher Encode": { - module: "Ciphers", - description: "The Affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using simple mathematical function, (ax + b) % 26, and converted back to a letter.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "a", - type: "number", - value: "Cipher.AFFINE_A" - }, - { - name: "b", - type: "number", - value: "Cipher.AFFINE_B" - } - ] - }, - "Affine Cipher Decode": { - module: "Ciphers", - description: "The Affine cipher is a type of monoalphabetic substitution cipher. To decrypt, each letter in an alphabet is mapped to its numeric equivalent, decrypted by a mathematical function, and converted back to a letter.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "a", - type: "number", - value: "Cipher.AFFINE_A" - }, - { - name: "b", - type: "number", - value: "Cipher.AFFINE_B" - } - ] - }, - "Atbash Cipher": { - module: "Ciphers", - description: "Atbash is a mono-alphabetic substitution cipher originally used to encode the Hebrew alphabet. It has been modified here for use with the Latin alphabet.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [] - }, - "Rotate right": { - module: "Default", - description: "Rotates each byte to the right by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Amount", - type: "number", - value: "Rotate.ROTATE_AMOUNT" - }, - { - name: "Carry through", - type: "boolean", - value: "Rotate.ROTATE_CARRY" - } - ] - }, - "Rotate left": { - module: "Default", - description: "Rotates each byte to the left by the number of bits specified, optionally carrying the excess bits over to the next byte. Currently only supports 8-bit values.", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Amount", - type: "number", - value: "Rotate.ROTATE_AMOUNT" - }, - { - name: "Carry through", - type: "boolean", - value: "Rotate.ROTATE_CARRY" - } - ] - }, - "ROT13": { - module: "Default", - description: "A simple caesar substitution cipher which rotates alphabet characters by the specified amount (default 13).", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Rotate lower case chars", - type: "boolean", - value: "Rotate.ROT13_LOWERCASE" - }, - { - name: "Rotate upper case chars", - type: "boolean", - value: "Rotate.ROT13_UPPERCASE" - }, - { - name: "Amount", - type: "number", - value: "Rotate.ROT13_AMOUNT" - }, - ] - }, - "ROT47": { - module: "Default", - description: "A slightly more complex variation of a caesar cipher, which includes ASCII characters from 33 '!' to 126 '~'. Default rotation: 47.", - highlight: true, - highlightReverse: true, - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Amount", - type: "number", - value: "Rotate.ROT47_AMOUNT" - }, - ] - }, - "Strip HTTP headers": { - module: "HTTP", - description: "Removes HTTP headers from a request or response by looking for the first instance of a double newline.", - inputType: "string", - outputType: "string", - args: [] - }, - "Parse User Agent": { - module: "HTTP", - description: "Attempts to identify and categorise information contained in a user-agent string.", - inputType: "string", - outputType: "string", - args: [] - }, - "Format MAC addresses": { - module: "Default", - description: "Displays given MAC addresses in multiple different formats.

Expects addresses in a list separated by newlines, spaces or commas.

WARNING: There are no validity checks.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Output case", - type: "option", - value: "MAC.OUTPUT_CASE" - }, - { - name: "No delimiter", - type: "boolean", - value: "MAC.NO_DELIM" - }, - { - name: "Dash delimiter", - type: "boolean", - value: "MAC.DASH_DELIM" - }, - { - name: "Colon delimiter", - type: "boolean", - value: "MAC.COLON_DELIM" - }, - { - name: "Cisco style", - type: "boolean", - value: "MAC.CISCO_STYLE" - }, - { - name: "IPv6 interface ID", - type: "boolean", - value: "MAC.IPV6_INTERFACE_ID" - } - ] - }, - "Encode NetBIOS Name": { - module: "Default", - description: "NetBIOS names as seen across the client interface to NetBIOS are exactly 16 bytes long. Within the NetBIOS-over-TCP protocols, a longer representation is used.

There are two levels of encoding. The first level maps a NetBIOS name into a domain system name. The second level maps the domain system name into the 'compressed' representation required for interaction with the domain name system.

This operation carries out the first level of encoding. See RFC 1001 for full details.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Offset", - type: "number", - value: "NetBIOS.OFFSET" - } - ] - }, - "Decode NetBIOS Name": { - module: "Default", - description: "NetBIOS names as seen across the client interface to NetBIOS are exactly 16 bytes long. Within the NetBIOS-over-TCP protocols, a longer representation is used.

There are two levels of encoding. The first level maps a NetBIOS name into a domain system name. The second level maps the domain system name into the 'compressed' representation required for interaction with the domain name system.

This operation decodes the first level of encoding. See RFC 1001 for full details.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Offset", - type: "number", - value: "NetBIOS.OFFSET" - } - ] - }, - "Offset checker": { - module: "Default", - description: "Compares multiple inputs (separated by the specified delimiter) and highlights matching characters which appear at the same position in all samples.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Sample delimiter", - type: "binaryString", - value: "StrUtils.OFF_CHK_SAMPLE_DELIMITER" - } - ] - }, - "Remove whitespace": { - module: "Default", - description: "Optionally removes all spaces, carriage returns, line feeds, tabs and form feeds from the input data.

This operation also supports the removal of full stops which are sometimes used to represent non-printable bytes in ASCII output.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Spaces", - type: "boolean", - value: "Tidy.REMOVE_SPACES" - }, - { - name: "Carriage returns (\\r)", - type: "boolean", - value: "Tidy.REMOVE_CARIAGE_RETURNS" - }, - { - name: "Line feeds (\\n)", - type: "boolean", - value: "Tidy.REMOVE_LINE_FEEDS" - }, - { - name: "Tabs", - type: "boolean", - value: "Tidy.REMOVE_TABS" - }, - { - name: "Form feeds (\\f)", - type: "boolean", - value: "Tidy.REMOVE_FORM_FEEDS" - }, - { - name: "Full stops", - type: "boolean", - value: "Tidy.REMOVE_FULL_STOPS" - } - ] - }, - "Remove null bytes": { - module: "Default", - description: "Removes all null bytes (0x00) from the input.", - inputType: "byteArray", - outputType: "byteArray", - args: [] - }, - "Drop bytes": { - module: "Default", - description: "Cuts a slice of the specified number of bytes out of the data.", - inputType: "ArrayBuffer", - outputType: "ArrayBuffer", - args: [ - { - name: "Start", - type: "number", - value: "Tidy.DROP_START" - }, - { - name: "Length", - type: "number", - value: "Tidy.DROP_LENGTH" - }, - { - name: "Apply to each line", - type: "boolean", - value: "Tidy.APPLY_TO_EACH_LINE" - } - ] - }, - "Take bytes": { - module: "Default", - description: "Takes a slice of the specified number of bytes from the data.", - inputType: "ArrayBuffer", - outputType: "ArrayBuffer", - args: [ - { - name: "Start", - type: "number", - value: "Tidy.TAKE_START" - }, - { - name: "Length", - type: "number", - value: "Tidy.TAKE_LENGTH" - }, - { - name: "Apply to each line", - type: "boolean", - value: "Tidy.APPLY_TO_EACH_LINE" - } - ] - }, - "Pad lines": { - module: "Default", - description: "Add the specified number of the specified character to the beginning or end of each line", - inputType: "string", - outputType: "string", - args: [ - { - name: "Position", - type: "option", - value: "Tidy.PAD_POSITION" - }, - { - name: "Length", - type: "number", - value: "Tidy.PAD_LENGTH" - }, - { - name: "Character", - type: "binaryShortString", - value: "Tidy.PAD_CHAR" - } - ] - }, - "Reverse": { - module: "Default", - description: "Reverses the input string.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "By", - type: "option", - value: "SeqUtils.REVERSE_BY" - } - ] - }, - "Sort": { - module: "Default", - description: "Alphabetically sorts strings separated by the specified delimiter.

The IP address option supports IPv4 only.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: "SeqUtils.DELIMITER_OPTIONS" - }, - { - name: "Reverse", - type: "boolean", - value: "SeqUtils.SORT_REVERSE" - }, - { - name: "Order", - type: "option", - value: "SeqUtils.SORT_ORDER" - } - ] - }, - "Unique": { - module: "Default", - description: "Removes duplicate strings from the input.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: "SeqUtils.DELIMITER_OPTIONS" - } - ] - }, - "Count occurrences": { - module: "Default", - description: "Counts the number of times the provided string occurs in the input.", - inputType: "string", - outputType: "number", - args: [ - { - name: "Search string", - type: "toggleString", - value: "", - toggleValues: "SeqUtils.SEARCH_TYPE" - } - ] - }, - "Add line numbers": { - module: "Default", - description: "Adds line numbers to the output.", - inputType: "string", - outputType: "string", - args: [] - }, - "Remove line numbers": { - module: "Default", - description: "Removes line numbers from the output if they can be trivially detected.", - inputType: "string", - outputType: "string", - args: [] - }, - "Find / Replace": { - module: "Regex", - description: "Replaces all occurrences of the first string with the second.

Includes support for regular expressions (regex), simple strings and extended strings (which support \\n, \\r, \\t, \\b, \\f and escaped hex bytes using \\x notation, e.g. \\x00 for a null byte).", - inputType: "string", - outputType: "string", - args: [ - { - name: "Find", - type: "toggleString", - value: "", - toggleValues: "Regex.SEARCH_TYPE" - }, - { - name: "Replace", - type: "binaryString", - value: "" - }, - { - name: "Global match", - type: "boolean", - value: "Regex.FIND_REPLACE_GLOBAL," - }, - { - name: "Case insensitive", - type: "boolean", - value: "Regex.FIND_REPLACE_CASE," - }, - { - name: "Multiline matching", - type: "boolean", - value: "Regex.FIND_REPLACE_MULTILINE," - }, - - ] - }, - "To Upper case": { - module: "Default", - description: "Converts the input string to upper case, optionally limiting scope to only the first character in each word, sentence or paragraph.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Scope", - type: "option", - value: "StrUtils.CASE_SCOPE" - } - ] - }, - "To Lower case": { - module: "Default", - description: "Converts every character in the input to lower case.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [] - }, - "Split": { - module: "Default", - description: "Splits a string into sections around a given delimiter.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Split delimiter", - type: "editableOption", - value: "StrUtils.SPLIT_DELIM_OPTIONS" - }, - { - name: "Join delimiter", - type: "editableOption", - value: "StrUtils.JOIN_DELIM_OPTIONS" - } - ] - }, - "Filter": { - module: "Default", - description: "Splits up the input using the specified delimiter and then filters each branch based on a regular expression.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: "StrUtils.DELIMITER_OPTIONS" - }, - { - name: "Regex", - type: "string", - value: "" - }, - { - name: "Invert condition", - type: "boolean", - value: false - }, - ] - }, - "Strings": { - module: "Regex", - description: "Extracts all strings from the input.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Encoding", - type: "option", - value: "Extract.ENCODING_LIST" - }, - { - name: "Minimum length", - type: "number", - value: "Extract.MIN_STRING_LEN" - }, - { - name: "Match", - type: "option", - value: "Extract.STRING_MATCH_TYPE" - }, - { - name: "Display total", - type: "boolean", - value: "Extract.DISPLAY_TOTAL" - } - ] - }, - "Extract IP addresses": { - module: "Regex", - description: "Extracts all IPv4 and IPv6 addresses.

Warning: Given a string 710.65.0.456, this will match 10.65.0.45 so always check the original input!", - inputType: "string", - outputType: "string", - args: [ - { - name: "IPv4", - type: "boolean", - value: "Extract.INCLUDE_IPV4" - }, - { - name: "IPv6", - type: "boolean", - value: "Extract.INCLUDE_IPV6" - }, - { - name: "Remove local IPv4 addresses", - type: "boolean", - value: "Extract.REMOVE_LOCAL" - }, - { - name: "Display total", - type: "boolean", - value: "Extract.DISPLAY_TOTAL" - } - ] - }, - "Extract email addresses": { - module: "Regex", - description: "Extracts all email addresses from the input.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Display total", - type: "boolean", - value: "Extract.DISPLAY_TOTAL" - } - ] - }, - "Extract MAC addresses": { - module: "Regex", - description: "Extracts all Media Access Control (MAC) addresses from the input.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Display total", - type: "boolean", - value: "Extract.DISPLAY_TOTAL" - } - ] - }, - "Extract URLs": { - module: "Regex", - description: "Extracts Uniform Resource Locators (URLs) from the input. The protocol (http, ftp etc.) is required otherwise there will be far too many false positives.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Display total", - type: "boolean", - value: "Extract.DISPLAY_TOTAL" - } - ] - }, - "Extract domains": { - module: "Regex", - description: "Extracts domain names.
Note that this will not include paths. Use Extract URLs to find entire URLs.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Display total", - type: "boolean", - value: "Extract.DISPLAY_TOTAL" - } - ] - }, - "Extract file paths": { - module: "Regex", - description: "Extracts anything that looks like a Windows or UNIX file path.

Note that if UNIX is selected, there will likely be a lot of false positives.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Windows", - type: "boolean", - value: "Extract.INCLUDE_WIN_PATH" - }, - { - name: "UNIX", - type: "boolean", - value: "Extract.INCLUDE_UNIX_PATH" - }, - { - name: "Display total", - type: "boolean", - value: "Extract.DISPLAY_TOTAL" - } - ] - }, - "Extract dates": { - module: "Regex", - description: "Extracts dates in the following formats
  • yyyy-mm-dd
  • dd/mm/yyyy
  • mm/dd/yyyy
Dividers can be any of /, -, . or space", - inputType: "string", - outputType: "string", - args: [ - { - name: "Display total", - type: "boolean", - value: "Extract.DISPLAY_TOTAL" - } - ] - }, - "Regular expression": { - module: "Regex", - description: "Define your own regular expression (regex) to search the input data with, optionally choosing from a list of pre-defined patterns.

Supports extended regex syntax including the 'dot matches all' flag, named capture groups, full unicode coverage (including \\p{} categories and scripts as well as astral codes) and recursive matching.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Built in regexes", - type: "populateOption", - value: "Regex.REGEX_PRE_POPULATE", - target: 1, - }, - { - name: "Regex", - type: "text", - value: "" - }, - { - name: "Case insensitive", - type: "boolean", - value: true - }, - { - name: "^ and $ match at newlines", - type: "boolean", - value: true - }, - { - name: "Dot matches all", - type: "boolean", - value: false - }, - { - name: "Unicode support", - type: "boolean", - value: false - }, - { - name: "Astral support", - type: "boolean", - value: false - }, - { - name: "Display total", - type: "boolean", - value: "Regex.DISPLAY_TOTAL" - }, - { - name: "Output format", - type: "option", - value: "Regex.OUTPUT_FORMAT" - }, - ] - }, - "XPath expression": { - module: "Code", - description: "Extract information from an XML document with an XPath query", - inputType: "string", - outputType: "string", - args: [ - { - name: "XPath", - type: "string", - value: "Code.XPATH_INITIAL" - }, - { - name: "Result delimiter", - type: "binaryShortString", - value: "Code.XPATH_DELIMITER" - } - ] - }, - "JPath expression": { - module: "Code", - description: "Extract information from a JSON object with a JPath query.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Query", - type: "string", - value: "Code.JPATH_INITIAL" - }, - { - name: "Result delimiter", - type: "binaryShortString", - value: "Code.JPATH_DELIMITER" - } - ] - }, - "CSS selector": { - module: "Code", - description: "Extract information from an HTML document with a CSS selector", - inputType: "string", - outputType: "string", - args: [ - { - name: "CSS selector", - type: "string", - value: "Code.CSS_SELECTOR_INITIAL" - }, - { - name: "Delimiter", - type: "binaryShortString", - value: "Code.CSS_QUERY_DELIMITER" - }, - ] - }, - "From UNIX Timestamp": { - module: "Default", - description: "Converts a UNIX timestamp to a datetime string.

e.g. 978346800 becomes Mon 1 January 2001 11:00:00 UTC

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).", - inputType: "number", - outputType: "string", - args: [ - { - name: "Units", - type: "option", - value: "DateTime.UNITS" - } - ], - patterns: [ - { - match: "^1?\\d{9}$", - flags: "", - args: ["Seconds (s)"] - }, - { - match: "^1?\\d{12}$", - flags: "", - args: ["Milliseconds (ms)"] - }, - { - match: "^1?\\d{15}$", - flags: "", - args: ["Microseconds (μs)"] - }, - { - match: "^1?\\d{18}$", - flags: "", - args: ["Nanoseconds (ns)"] - }, - ] - }, - "To UNIX Timestamp": { - module: "Default", - description: "Parses a datetime string in UTC and returns the corresponding UNIX timestamp.

e.g. Mon 1 January 2001 11:00:00 becomes 978346800

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).", - inputType: "string", - outputType: "string", - args: [ - { - name: "Units", - type: "option", - value: "DateTime.UNITS" - }, - { - name: "Treat as UTC", - type: "boolean", - value: "DateTime.TREAT_AS_UTC" - }, - { - name: "Show parsed datetime", - type: "boolean", - value: true - } - ] - }, - "Sleep": { - module: "Default", - description: "Sleep causes the recipe to wait for a specified number of milliseconds before continuing execution.", - inputType: "ArrayBuffer", - outputType: "ArrayBuffer", - args: [ - { - name: "Time (ms)", - type: "number", - value: 1000 - } - ] - }, - "Windows Filetime to UNIX Timestamp": { - module: "Default", - description: "Converts a Windows Filetime value to a UNIX timestamp.

A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).

This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Output units", - type: "option", - value: "Filetime.UNITS" - }, - { - name: "Input format", - type: "option", - value: "Filetime.FILETIME_FORMATS" - } - ] - }, - "UNIX Timestamp to Windows Filetime": { - module: "Default", - description: "Converts a UNIX timestamp to a Windows Filetime value.

A Windows Filetime is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 UTC.

A UNIX timestamp is a 32-bit value representing the number of seconds since January 1, 1970 UTC (the UNIX epoch).

This operation also supports UNIX timestamps in milliseconds, microseconds and nanoseconds.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Input units", - type: "option", - value: "Filetime.UNITS" - }, - { - name: "Output format", - type: "option", - value: "Filetime.FILETIME_FORMATS" - } - ] - }, - "Translate DateTime Format": { - module: "Default", - description: "Parses a datetime string in one format and re-writes it in another.

Run with no input to see the relevant format string examples.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Built in formats", - type: "populateOption", - value: "DateTime.DATETIME_FORMATS", - target: 1 - }, - { - name: "Input format string", - type: "binaryString", - value: "DateTime.INPUT_FORMAT_STRING" - }, - { - name: "Input timezone", - type: "option", - value: "DateTime.TIMEZONES" - }, - { - name: "Output format string", - type: "binaryString", - value: "DateTime.OUTPUT_FORMAT_STRING" - }, - { - name: "Output timezone", - type: "option", - value: "DateTime.TIMEZONES" - } - ] - }, - "Parse DateTime": { - module: "Default", - description: "Parses a DateTime string in your specified format and displays it in whichever timezone you choose with the following information:
  • Date
  • Time
  • Period (AM/PM)
  • Timezone
  • UTC offset
  • Daylight Saving Time
  • Leap year
  • Days in this month
  • Day of year
  • Week number
  • Quarter
Run with no input to see format string examples if required.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Built in formats", - type: "populateOption", - value: "DateTime.DATETIME_FORMATS", - target: 1 - }, - { - name: "Input format string", - type: "binaryString", - value: "DateTime.INPUT_FORMAT_STRING" - }, - { - name: "Input timezone", - type: "option", - value: "DateTime.TIMEZONES" - }, - ] - }, - "Convert distance": { - module: "Default", - description: "Converts a unit of distance to another format.", - inputType: "BigNumber", - outputType: "BigNumber", - args: [ - { - name: "Input units", - type: "option", - value: "Convert.DISTANCE_UNITS" - }, - { - name: "Output units", - type: "option", - value: "Convert.DISTANCE_UNITS" - } - ] - }, - "Convert area": { - module: "Default", - description: "Converts a unit of area to another format.", - inputType: "BigNumber", - outputType: "BigNumber", - args: [ - { - name: "Input units", - type: "option", - value: "Convert.AREA_UNITS" - }, - { - name: "Output units", - type: "option", - value: "Convert.AREA_UNITS" - } - ] - }, - "Convert mass": { - module: "Default", - description: "Converts a unit of mass to another format.", - inputType: "BigNumber", - outputType: "BigNumber", - args: [ - { - name: "Input units", - type: "option", - value: "Convert.MASS_UNITS" - }, - { - name: "Output units", - type: "option", - value: "Convert.MASS_UNITS" - } - ] - }, - "Convert speed": { - module: "Default", - description: "Converts a unit of speed to another format.", - inputType: "BigNumber", - outputType: "BigNumber", - args: [ - { - name: "Input units", - type: "option", - value: "Convert.SPEED_UNITS" - }, - { - name: "Output units", - type: "option", - value: "Convert.SPEED_UNITS" - } - ] - }, - "Convert data units": { - module: "Default", - description: "Converts a unit of data to another format.", - inputType: "BigNumber", - outputType: "BigNumber", - args: [ - { - name: "Input units", - type: "option", - value: "Convert.DATA_UNITS" - }, - { - name: "Output units", - type: "option", - value: "Convert.DATA_UNITS" - } - ] - }, - "Raw Deflate": { - module: "Compression", - description: "Compresses data using the deflate algorithm with no headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Compression type", - type: "option", - value: "Compress.COMPRESSION_TYPE" - } - ] - }, - "Raw Inflate": { - module: "Compression", - description: "Decompresses data which has been compressed using the deflate algorithm with no headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Start index", - type: "number", - value: "Compress.INFLATE_INDEX" - }, - { - name: "Initial output buffer size", - type: "number", - value: "Compress.INFLATE_BUFFER_SIZE" - }, - { - name: "Buffer expansion type", - type: "option", - value: "Compress.INFLATE_BUFFER_TYPE" - }, - { - name: "Resize buffer after decompression", - type: "boolean", - value: "Compress.INFLATE_RESIZE" - }, - { - name: "Verify result", - type: "boolean", - value: "Compress.INFLATE_VERIFY" - } - ] - }, - "Zlib Deflate": { - module: "Compression", - description: "Compresses data using the deflate algorithm adding zlib headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Compression type", - type: "option", - value: "Compress.COMPRESSION_TYPE" - } - ] - }, - "Zlib Inflate": { - module: "Compression", - description: "Decompresses data which has been compressed using the deflate algorithm with zlib headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Start index", - type: "number", - value: "Compress.INFLATE_INDEX" - }, - { - name: "Initial output buffer size", - type: "number", - value: "Compress.INFLATE_BUFFER_SIZE" - }, - { - name: "Buffer expansion type", - type: "option", - value: "Compress.INFLATE_BUFFER_TYPE" - }, - { - name: "Resize buffer after decompression", - type: "boolean", - value: "Compress.INFLATE_RESIZE" - }, - { - name: "Verify result", - type: "boolean", - value: "Compress.INFLATE_VERIFY" - } - ], - patterns: [ - { - match: "^\\x78(\\x01|\\x9c|\\xda|\\x5e)", - flags: "", - args: [0, 0, "Adaptive", false, false] - }, - ] - }, - "Gzip": { - module: "Compression", - description: "Compresses data using the deflate algorithm with gzip headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Compression type", - type: "option", - value: "Compress.COMPRESSION_TYPE" - }, - { - name: "Filename (optional)", - type: "string", - value: "" - }, - { - name: "Comment (optional)", - type: "string", - value: "" - }, - { - name: "Include file checksum", - type: "boolean", - value: "Compress.GZIP_CHECKSUM" - } - ] - }, - "Gunzip": { - module: "Compression", - description: "Decompresses data which has been compressed using the deflate algorithm with gzip headers.", - inputType: "byteArray", - outputType: "byteArray", - args: [], - patterns: [ - { - match: "^\\x1f\\x8b\\x08", - flags: "", - args: [] - }, - ] - }, - "Zip": { - module: "Compression", - description: "Compresses data using the PKZIP algorithm with the given filename.

No support for multiple files at this time.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Filename", - type: "string", - value: "Compress.PKZIP_FILENAME" - }, - { - name: "Comment", - type: "string", - value: "" - }, - { - name: "Password", - type: "binaryString", - value: "" - }, - { - name: "Compression method", - type: "option", - value: "Compress.COMPRESSION_METHOD" - }, - { - name: "Operating system", - type: "option", - value: "Compress.OS" - }, - { - name: "Compression type", - type: "option", - value: "Compress.COMPRESSION_TYPE" - } - ] - }, - "Unzip": { - module: "Compression", - description: "Decompresses data using the PKZIP algorithm and displays it per file, with support for passwords.", - inputType: "byteArray", - outputType: "html", - args: [ - { - name: "Password", - type: "binaryString", - value: "" - }, - { - name: "Verify result", - type: "boolean", - value: "Compress.PKUNZIP_VERIFY" - } - ], - patterns: [ - { - match: "^\\x50\\x4b(?:\\x03|\\x05|\\x07)(?:\\x04|\\x06|\\x08)", - flags: "", - args: ["", false] - }, - ] - }, - "Bzip2 Decompress": { - module: "Compression", - description: "Decompresses data using the Bzip2 algorithm.", - inputType: "byteArray", - outputType: "string", - args: [], - patterns: [ - { - match: "^\\x42\\x5a\\x68", - flags: "", - args: [] - }, - ] - }, - "Generic Code Beautify": { - module: "Code", - description: "Attempts to pretty print C-style languages such as C, C++, C#, Java, PHP, JavaScript etc.

This will not do a perfect job, and the resulting code may not work any more. This operation is designed purely to make obfuscated or minified code more easy to read and understand.

Things which will not work properly:
  • For loop formatting
  • Do-While loop formatting
  • Switch/Case indentation
  • Certain bit shift operators
", - inputType: "string", - outputType: "string", - args: [] - }, - "JavaScript Parser": { - module: "Code", - description: "Returns an Abstract Syntax Tree for valid JavaScript code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Location info", - type: "boolean", - value: "JS.PARSE_LOC" - }, - { - name: "Range info", - type: "boolean", - value: "JS.PARSE_RANGE" - }, - { - name: "Include tokens array", - type: "boolean", - value: "JS.PARSE_TOKENS" - }, - { - name: "Include comments array", - type: "boolean", - value: "JS.PARSE_COMMENT" - }, - { - name: "Report errors and try to continue", - type: "boolean", - value: "JS.PARSE_TOLERANT" - }, - ] - }, - "JavaScript Beautify": { - module: "Code", - description: "Parses and pretty prints valid JavaScript code. Also works with JavaScript Object Notation (JSON).", - inputType: "string", - outputType: "string", - args: [ - { - name: "Indent string", - type: "binaryShortString", - value: "JS.BEAUTIFY_INDENT" - }, - { - name: "Quotes", - type: "option", - value: "JS.BEAUTIFY_QUOTES" - }, - { - name: "Semicolons before closing braces", - type: "boolean", - value: "JS.BEAUTIFY_SEMICOLONS" - }, - { - name: "Include comments", - type: "boolean", - value: "JS.BEAUTIFY_COMMENT" - }, - ] - }, - "JavaScript Minify": { - module: "Code", - description: "Compresses JavaScript code.", - inputType: "string", - outputType: "string", - args: [] - }, - "XML Beautify": { - module: "Code", - description: "Indents and prettifies eXtensible Markup Language (XML) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Indent string", - type: "binaryShortString", - value: "Code.BEAUTIFY_INDENT" - } - ] - }, - "JSON Beautify": { - module: "Code", - description: "Indents and prettifies JavaScript Object Notation (JSON) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Indent string", - type: "binaryShortString", - value: "Code.BEAUTIFY_INDENT" - } - ] - }, - "CSS Beautify": { - module: "Code", - description: "Indents and prettifies Cascading Style Sheets (CSS) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Indent string", - type: "binaryShortString", - value: "Code.BEAUTIFY_INDENT" - } - ] - }, - "SQL Beautify": { - module: "Code", - description: "Indents and prettifies Structured Query Language (SQL) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Indent string", - type: "binaryShortString", - value: "Code.BEAUTIFY_INDENT" - } - ] - }, - "XML Minify": { - module: "Code", - description: "Compresses eXtensible Markup Language (XML) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Preserve comments", - type: "boolean", - value: "Code.PRESERVE_COMMENTS" - } - ] - }, - "JSON Minify": { - module: "Code", - description: "Compresses JavaScript Object Notation (JSON) code.", - inputType: "string", - outputType: "string", - args: [] - }, - "CSS Minify": { - module: "Code", - description: "Compresses Cascading Style Sheets (CSS) code.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Preserve comments", - type: "boolean", - value: "Code.PRESERVE_COMMENTS" - } - ] - }, - "SQL Minify": { - module: "Code", - description: "Compresses Structured Query Language (SQL) code.", - inputType: "string", - outputType: "string", - args: [] - }, - "Analyse hash": { - module: "Hashing", - description: "Tries to determine information about a given hash and suggests which algorithm may have been used to generate it based on its length.", - inputType: "string", - outputType: "string", - args: [] - }, - "MD2": { - module: "Hashing", - description: "The MD2 (Message-Digest 2) algorithm is a cryptographic hash function developed by Ronald Rivest in 1989. The algorithm is optimized for 8-bit computers.

Although MD2 is no longer considered secure, even as of 2014, it remains in use in public key infrastructures as part of certificates generated with MD2 and RSA.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "MD4": { - module: "Hashing", - description: "The MD4 (Message-Digest 4) algorithm is a cryptographic hash function developed by Ronald Rivest in 1990. The digest length is 128 bits. The algorithm has influenced later designs, such as the MD5, SHA-1 and RIPEMD algorithms.

The security of MD4 has been severely compromised.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "MD5": { - module: "Hashing", - description: "MD5 (Message-Digest 5) is a widely used hash function. It has been used in a variety of security applications and is also commonly used to check the integrity of files.

However, MD5 is not collision resistant and it isn't suitable for applications like SSL/TLS certificates or digital signatures that rely on this property.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "MD6": { - module: "Hashing", - description: "The MD6 (Message-Digest 6) algorithm is a cryptographic hash function. It uses a Merkle tree-like structure to allow for immense parallel computation of hashes for very long inputs.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Size", - type: "number", - value: "Hash.MD6_SIZE" - }, - { - name: "Levels", - type: "number", - value: "Hash.MD6_LEVELS" - }, - { - name: "Key", - type: "string", - value: "" - } - ] - }, - "SHA0": { - module: "Hashing", - description: "SHA-0 is a retronym applied to the original version of the 160-bit hash function published in 1993 under the name 'SHA'. It was withdrawn shortly after publication due to an undisclosed 'significant flaw' and replaced by the slightly revised version SHA-1.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "SHA1": { - module: "Hashing", - description: "The SHA (Secure Hash Algorithm) hash functions were designed by the NSA. SHA-1 is the most established of the existing SHA hash functions and it is used in a variety of security applications and protocols.

However, SHA-1's collision resistance has been weakening as new attacks are discovered or improved.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "SHA2": { - module: "Hashing", - description: "The SHA-2 (Secure Hash Algorithm 2) hash functions were designed by the NSA. SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA224, SHA256, SHA384, SHA512.

  • SHA-512 operates on 64-bit words.
  • SHA-256 operates on 32-bit words.
  • SHA-384 is largely identical to SHA-512 but is truncated to 384 bytes.
  • SHA-224 is largely identical to SHA-256 but is truncated to 224 bytes.
  • SHA-512/224 and SHA-512/256 are truncated versions of SHA-512, but the initial values are generated using the method described in Federal Information Processing Standards (FIPS) PUB 180-4.
", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Size", - type: "option", - value: "Hash.SHA2_SIZE" - } - ] - }, - "SHA3": { - module: "Hashing", - description: "The SHA-3 (Secure Hash Algorithm 3) hash functions were released by NIST on August 5, 2015. Although part of the same series of standards, SHA-3 is internally quite different from the MD5-like structure of SHA-1 and SHA-2.

SHA-3 is a subset of the broader cryptographic primitive family Keccak designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche, building upon RadioGatún.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Size", - type: "option", - value: "Hash.SHA3_SIZE" - } - ] - }, - "Keccak": { - module: "Hashing", - description: "The Keccak hash algorithm was designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche, building upon RadioGatún. It was selected as the winner of the SHA-3 design competition.

This version of the algorithm is Keccak[c=2d] and differs from the SHA-3 specification.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Size", - type: "option", - value: "Hash.KECCAK_SIZE" - } - ] - }, - "Shake": { - module: "Hashing", - description: "Shake is an Extendable Output Function (XOF) of the SHA-3 hash algorithm, part of the Keccak family, allowing for variable output length/size.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Capacity", - type: "option", - value: "Hash.SHAKE_CAPACITY" - }, - { - name: "Size", - type: "number", - value: "Hash.SHAKE_SIZE" - } - ] - - }, - "RIPEMD": { - module: "Hashing", - description: "RIPEMD (RACE Integrity Primitives Evaluation Message Digest) is a family of cryptographic hash functions developed in Leuven, Belgium, by Hans Dobbertin, Antoon Bosselaers and Bart Preneel at the COSIC research group at the Katholieke Universiteit Leuven, and first published in 1996.

RIPEMD was based upon the design principles used in MD4, and is similar in performance to the more popular SHA-1.

", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Size", - type: "option", - value: "Hash.RIPEMD_SIZE" - } - ] - }, - "HAS-160": { - module: "Hashing", - description: "HAS-160 is a cryptographic hash function designed for use with the Korean KCDSA digital signature algorithm. It is derived from SHA-1, with assorted changes intended to increase its security. It produces a 160-bit output.

HAS-160 is used in the same way as SHA-1. First it divides input in blocks of 512 bits each and pads the final block. A digest function updates the intermediate hash value by processing the input blocks in turn.

The message digest algorithm consists of 80 rounds.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "Whirlpool": { - module: "Hashing", - description: "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.

Several variants exist:
  • Whirlpool-0 is the original version released in 2000.
  • Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.
  • Wirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.
", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Variant", - type: "option", - value: "Hash.WHIRLPOOL_VARIANT" - } - ] - }, - "Snefru": { - module: "Hashing", - description: "Snefru is a cryptographic hash function invented by Ralph Merkle in 1990 while working at Xerox PARC. The function supports 128-bit and 256-bit output. It was named after the Egyptian Pharaoh Sneferu, continuing the tradition of the Khufu and Khafre block ciphers.

The original design of Snefru was shown to be insecure by Eli Biham and Adi Shamir who were able to use differential cryptanalysis to find hash collisions. The design was then modified by increasing the number of iterations of the main pass of the algorithm from two to eight.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Rounds", - type: "option", - value: "Hash.SNEFRU_ROUNDS" - }, - { - name: "Size", - type: "option", - value: "Hash.SNEFRU_SIZE" - } - ] - }, - "SSDEEP": { - module: "Hashing", - description: "SSDEEP is a program for computing context triggered piecewise hashes (CTPH). Also called fuzzy hashes, CTPH can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length.

SSDEEP hashes are now widely used for simple identification purposes (e.g. the 'Basic Properties' section in VirusTotal). Although 'better' fuzzy hashes are available, SSDEEP is still one of the primary choices because of its speed and being a de facto standard.

This operation is fundamentally the same as the CTPH operation, however their outputs differ in format.", - inputType: "string", - outputType: "string", - args: [] - }, - "CTPH": { - module: "Hashing", - description: "Context Triggered Piecewise Hashing, also called Fuzzy Hashing, can match inputs that have homologies. Such inputs have sequences of identical bytes in the same order, although bytes in between these sequences may be different in both content and length.

CTPH was originally based on the work of Dr. Andrew Tridgell and a spam email detector called SpamSum. This method was adapted by Jesse Kornblum and published at the DFRWS conference in 2006 in a paper 'Identifying Almost Identical Files Using Context Triggered Piecewise Hashing'.", - inputType: "string", - outputType: "string", - args: [] - }, - "Compare SSDEEP hashes": { - module: "Hashing", - description: "Compares two SSDEEP fuzzy hashes to determine the similarity between them on a scale of 0 to 100.", - inputType: "string", - outputType: "Number", - args: [ - { - name: "Delimiter", - type: "option", - value: "Hash.DELIM_OPTIONS" - } - ] - }, - "Compare CTPH hashes": { - module: "Hashing", - description: "Compares two Context Triggered Piecewise Hashing (CTPH) fuzzy hashes to determine the similarity between them on a scale of 0 to 100.", - inputType: "string", - outputType: "Number", - args: [ - { - name: "Delimiter", - type: "option", - value: "Hash.DELIM_OPTIONS" - } - ] - }, - "HMAC": { - module: "Hashing", - description: "Keyed-Hash Message Authentication Codes (HMAC) are a mechanism for message authentication using cryptographic hash functions.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Key", - type: "binaryString", - value: "" - }, - { - name: "Hashing function", - type: "option", - value: "Hash.HMAC_FUNCTIONS" - }, - ] - }, - "Fletcher-8 Checksum": { - module: "Hashing", - description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "Fletcher-16 Checksum": { - module: "Hashing", - description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "Fletcher-32 Checksum": { - module: "Hashing", - description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "Fletcher-64 Checksum": { - module: "Hashing", - description: "The Fletcher checksum is an algorithm for computing a position-dependent checksum devised by John Gould Fletcher at Lawrence Livermore Labs in the late 1970s.

The objective of the Fletcher checksum was to provide error-detection properties approaching those of a cyclic redundancy check but with the lower computational effort associated with summation techniques.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "Adler-32 Checksum": { - module: "Hashing", - description: "Adler-32 is a checksum algorithm which was invented by Mark Adler in 1995, and is a modification of the Fletcher checksum. Compared to a cyclic redundancy check of the same length, it trades reliability for speed (preferring the latter).

Adler-32 is more reliable than Fletcher-16, and slightly less reliable than Fletcher-32.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "CRC-32 Checksum": { - module: "Hashing", - description: "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.

The CRC was invented by W. Wesley Peterson in 1961; the 32-bit CRC function of Ethernet and many other standards is the work of several researchers and was published in 1975.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "CRC-16 Checksum": { - module: "Hashing", - description: "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.

The CRC was invented by W. Wesley Peterson in 1961.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "Generate all hashes": { - module: "Hashing", - description: "Generates all available hashes and checksums for the input.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "Entropy": { - module: "Default", - description: "Calculates the Shannon entropy of the input data which gives an idea of its randomness. 8 is the maximum.", - inputType: "byteArray", - outputType: "html", - args: [ - { - name: "Chunk size", - type: "number", - value: "Entropy.CHUNK_SIZE" - } - ] - }, - "Frequency distribution": { - module: "Default", - description: "Displays the distribution of bytes in the data as a graph.", - inputType: "ArrayBuffer", - outputType: "html", - args: [ - { - name: "Show 0%'s", - type: "boolean", - value: "Entropy.FREQ_ZEROS" - } - ] - }, - "Chi Square": { - module: "Default", - description: "Calculates the Chi-Squared distribution of values.", - inputType: "ArrayBuffer", - outputType: "number", - args: [] - }, - "Numberwang": { - module: "Default", - description: "Based on the popular gameshow by Mitchell and Webb.", - inputType: "string", - outputType: "string", - args: [] - }, - "Parse X.509 certificate": { - module: "PublicKey", - description: "X.509 is an ITU-T standard for a public key infrastructure (PKI) and Privilege Management Infrastructure (PMI). It is commonly involved with SSL/TLS security.

This operation displays the contents of a certificate in a human readable format, similar to the openssl command line tool.

Tags: X509, server hello, handshake", - inputType: "string", - outputType: "string", - args: [ - { - name: "Input format", - type: "option", - value: "PublicKey.X509_INPUT_FORMAT" - } - ], - patterns: [ - { - match: "^-+BEGIN CERTIFICATE-+\\r?\\n[\\da-z+/\\n\\r]+-+END CERTIFICATE-+\\r?\\n?$", - flags: "i", - args: ["PEM"] - }, - ] - }, - "PEM to Hex": { - module: "PublicKey", - description: "Converts PEM (Privacy Enhanced Mail) format to a hexadecimal DER (Distinguished Encoding Rules) string.", - inputType: "string", - outputType: "string", - args: [] - }, - "Hex to PEM": { - module: "PublicKey", - description: "Converts a hexadecimal DER (Distinguished Encoding Rules) string into PEM (Privacy Enhanced Mail) format.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Header string", - type: "string", - value: "PublicKey.PEM_HEADER_STRING" - } - ] - }, - "Hex to Object Identifier": { - module: "PublicKey", - description: "Converts a hexadecimal string into an object identifier (OID).", - inputType: "string", - outputType: "string", - args: [] - }, - "Object Identifier to Hex": { - module: "PublicKey", - description: "Converts an object identifier (OID) into a hexadecimal string.", - inputType: "string", - outputType: "string", - args: [] - }, - "Parse ASN.1 hex string": { - module: "PublicKey", - description: "Abstract Syntax Notation One (ASN.1) is a standard and notation that describes rules and structures for representing, encoding, transmitting, and decoding data in telecommunications and computer networking.

This operation parses arbitrary ASN.1 data and presents the resulting tree.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Starting index", - type: "number", - value: 0 - }, - { - name: "Truncate octet strings longer than", - type: "number", - value: "PublicKey.ASN1_TRUNCATE_LENGTH" - } - ] - }, - "Detect File Type": { - module: "Default", - description: "Attempts to guess the MIME (Multipurpose Internet Mail Extensions) type of the data based on 'magic bytes'.

Currently supports the following file types: 7z, amr, avi, bmp, bz2, class, cr2, crx, dex, dmg, doc, elf, eot, epub, exe, flac, flv, gif, gz, ico, iso, jpg, jxr, m4a, m4v, mid, mkv, mov, mp3, mp4, mpg, ogg, otf, pdf, png, ppt, ps, psd, rar, rtf, sqlite, swf, tar, tar.z, tif, ttf, utf8, vmdk, wav, webm, webp, wmv, woff, woff2, xls, xz, zip.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "Scan for Embedded Files": { - module: "Default", - description: "Scans the data for potential embedded files by looking for magic bytes at all offsets. This operation is prone to false positives.

WARNING: Files over about 100KB in size will take a VERY long time to process.", - inputType: "ArrayBuffer", - outputType: "string", - args: [ - { - name: "Ignore common byte sequences", - type: "boolean", - value: "FileType.IGNORE_COMMON_BYTE_SEQUENCES" - } - ] - }, - "Expand alphabet range": { - module: "Default", - description: "Expand an alphabet range string into a list of the characters in that range.

e.g. a-z becomes abcdefghijklmnopqrstuvwxyz.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "binaryString", - value: "" - } - ] - }, - "Diff": { - module: "Diff", - description: "Compares two inputs (separated by the specified delimiter) and highlights the differences between them.", - inputType: "string", - outputType: "html", - args: [ - { - name: "Sample delimiter", - type: "binaryString", - value: "Diff.DIFF_SAMPLE_DELIMITER" - }, - { - name: "Diff by", - type: "option", - value: "Diff.DIFF_BY" - }, - { - name: "Show added", - type: "boolean", - value: true - }, - { - name: "Show removed", - type: "boolean", - value: true - }, - { - name: "Ignore whitespace (relevant for word and line)", - type: "boolean", - value: false - } - ] - }, - "Parse UNIX file permissions": { - module: "Default", - description: "Given a UNIX/Linux file permission string in octal or textual format, this operation explains which permissions are granted to which user groups.

Input should be in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format.", - inputType: "string", - outputType: "string", - args: [] - }, - "Swap endianness": { - module: "Default", - description: "Switches the data from big-endian to little-endian or vice-versa. Data can be read in as hexadecimal or raw bytes. It will be returned in the same format as it is entered.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "string", - args: [ - { - name: "Data format", - type: "option", - value: "Endian.DATA_FORMAT" - }, - { - name: "Word length (bytes)", - type: "number", - value: "Endian.WORD_LENGTH" - }, - { - name: "Pad incomplete words", - type: "boolean", - value: "Endian.PAD_INCOMPLETE_WORDS" - } - ] - }, - "Microsoft Script Decoder": { - module: "Default", - description: "Decodes Microsoft Encoded Script files that have been encoded with Microsoft's custom encoding. These are often VBS (Visual Basic Script) files that are encoded and renamed with a '.vbe' extention or JS (JScript) files renamed with a '.jse' extention.

Sample

Encoded:
#@~^RQAAAA==-mD~sX|:/TP{~J:+dYbxL~@!F@*@!+@*@!&@*eEI@#@&@#@&.jm.raY 214Wv:zms/obI0xEAAA==^#~@

Decoded:
var my_msg = "Testing <1><2><3>!";\n\nVScript.Echo(my_msg);", - inputType: "string", - outputType: "string", - args: [] - }, - "Syntax highlighter": { - module: "Code", - description: "Adds syntax highlighting to a range of source code languages. Note that this will not indent the code. Use one of the 'Beautify' operations for that.", - highlight: true, - highlightReverse: true, - inputType: "string", - outputType: "html", - args: [ - { - name: "Language", - type: "option", - value: "Code.LANGUAGES" - }, - ] - }, - "TCP/IP Checksum": { - module: "Hashing", - description: "Calculates the checksum for a TCP (Transport Control Protocol) or IP (Internet Protocol) header from an input of raw bytes.", - inputType: "byteArray", - outputType: "string", - args: [] - }, - "Parse colour code": { - module: "Default", - description: "Converts a colour code in a standard format to other standard formats and displays the colour itself.

Example inputs
  • #d9edf7
  • rgba(217,237,247,1)
  • hsla(200,65%,91%,1)
  • cmyk(0.12, 0.04, 0.00, 0.03)
", - inputType: "string", - outputType: "html", - args: [] - }, - "Generate UUID": { - module: "Default", - description: "Generates an RFC 4122 version 4 compliant Universally Unique Identifier (UUID), also known as a Globally Unique Identifier (GUID).

A version 4 UUID relies on random numbers, in this case generated using window.crypto if available and falling back to Math.random if not.", - inputType: "string", - outputType: "string", - args: [] - }, - "Substitute": { - module: "Ciphers", - description: "A substitution cipher allowing you to specify bytes to replace with other byte values. This can be used to create Caesar ciphers but is more powerful as any byte value can be substituted, not just letters, and the substitution values need not be in order.

Enter the bytes you want to replace in the Plaintext field and the bytes to replace them with in the Ciphertext field.

Non-printable bytes can be specified using string escape notation. For example, a line feed character can be written as either \\n or \\x0a.

Byte ranges can be specified using a hyphen. For example, the sequence 0123456789 can be written as 0-9.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Plaintext", - type: "binaryString", - value: "Cipher.SUBS_PLAINTEXT" - }, - { - name: "Ciphertext", - type: "binaryString", - value: "Cipher.SUBS_CIPHERTEXT" - } - ] - }, - "Escape string": { - module: "Default", - description: "Escapes special characters in a string so that they do not cause conflicts. For example, Don't stop me now becomes Don\\'t stop me now.

Supports the following escape sequences:
  • \\n (Line feed/newline)
  • \\r (Carriage return)
  • \\t (Horizontal tab)
  • \\b (Backspace)
  • \\f (Form feed)
  • \\xnn (Hex, where n is 0-f)
  • \\\\ (Backslash)
  • \\' (Single quote)
  • \\" (Double quote)
  • \\unnnn (Unicode character)
  • \\u{nnnnnn} (Unicode code point)
", - inputType: "string", - outputType: "string", - args: [ - { - name: "Escape level", - type: "option", - value: "StrUtils.ESCAPE_LEVEL" - }, - { - name: "Escape quote", - type: "option", - value: "StrUtils.QUOTE_TYPES" - }, - { - name: "JSON compatible", - type: "boolean", - value: false - }, - { - name: "ES6 compatible", - type: "boolean", - value: true - }, - { - name: "Uppercase hex", - type: "boolean", - value: false - } - ] - }, - "Unescape string": { - module: "Default", - description: "Unescapes characters in a string that have been escaped. For example, Don\\'t stop me now becomes Don't stop me now.

Supports the following escape sequences:
  • \\n (Line feed/newline)
  • \\r (Carriage return)
  • \\t (Horizontal tab)
  • \\b (Backspace)
  • \\f (Form feed)
  • \\xnn (Hex, where n is 0-f)
  • \\\\ (Backslash)
  • \\' (Single quote)
  • \\" (Double quote)
  • \\unnnn (Unicode character)
  • \\u{nnnnnn} (Unicode code point)
", - inputType: "string", - outputType: "string", - args: [] - }, - "To Morse Code": { - module: "Default", - description: "Translates alphanumeric characters into International Morse Code.

Ignores non-Morse characters.

e.g. SOS becomes ... --- ...", - inputType: "string", - outputType: "string", - args: [ - { - name: "Format options", - type: "option", - value: "MorseCode.FORMAT_OPTIONS" - }, - { - name: "Letter delimiter", - type: "option", - value: "MorseCode.LETTER_DELIM_OPTIONS" - }, - { - name: "Word delimiter", - type: "option", - value: "MorseCode.WORD_DELIM_OPTIONS" - } - ] - }, - "From Morse Code": { - module: "Default", - description: "Translates Morse Code into (upper case) alphanumeric characters.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Letter delimiter", - type: "option", - value: "MorseCode.LETTER_DELIM_OPTIONS" - }, - { - name: "Word delimiter", - type: "option", - value: "MorseCode.WORD_DELIM_OPTIONS" - } - ], - patterns: [ - { - match: "(?:^[-. \\n]{5,}$|^[_. \\n]{5,}$|^(?:dash|dot| |\\n){5,}$)", - flags: "i", - args: ["Space", "Line feed"] - }, - ] - }, - "Tar": { - module: "Compression", - description: "Packs the input into a tarball.

No support for multiple files at this time.", - inputType: "byteArray", - outputType: "byteArray", - args: [ - { - name: "Filename", - type: "string", - value: "Compress.TAR_FILENAME" - } - ] - }, - "Untar": { - module: "Compression", - description: "Unpacks a tarball and displays it per file.", - inputType: "byteArray", - outputType: "html", - args: [], - patterns: [ - { - match: "^.{257}\\x75\\x73\\x74\\x61\\x72", - flags: "", - args: [] - }, - ] - }, - "Head": { - module: "Default", - description: [ - "Like the UNIX head utility.", - "
", - "Gets the first n lines.", - "
", - "You can select all but the last n lines by entering a negative value for n.", - "
", - "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: "StrUtils.DELIMITER_OPTIONS" - }, - { - name: "Number", - type: "number", - value: 10, - }, - ] - }, - "Tail": { - module: "Default", - description: [ - "Like the UNIX tail utility.", - "
", - "Gets the last n lines.", - "
", - "Optionally you can select all lines after line n by entering a negative value for n.", - "
", - "The delimiter can be changed so that instead of lines, fields (i.e. commas) are selected instead.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "option", - value: "StrUtils.DELIMITER_OPTIONS" - }, - { - name: "Number", - type: "number", - value: 10, - }, - ] - }, - "To Snake case": { - module: "Code", - description: [ - "Converts the input string to snake case.", - "

", - "Snake case is all lower case with underscores as word boundaries.", - "

", - "e.g. this_is_snake_case", - "

", - "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Attempt to be context aware", - type: "boolean", - value: false, - }, - ] - }, - "To Camel case": { - module: "Code", - description: [ - "Converts the input string to camel case.", - "

", - "Camel case is all lower case except letters after word boundaries which are uppercase.", - "

", - "e.g. thisIsCamelCase", - "

", - "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Attempt to be context aware", - type: "boolean", - value: false, - }, - ] - }, - "To Kebab case": { - module: "Code", - description: [ - "Converts the input string to kebab case.", - "

", - "Kebab case is all lower case with dashes as word boundaries.", - "

", - "e.g. this-is-kebab-case", - "

", - "'Attempt to be context aware' will make the operation attempt to nicely transform variable and function names.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Attempt to be context aware", - type: "boolean", - value: false, - }, - ] - }, - "Extract EXIF": { - module: "Image", - description: [ - "Extracts EXIF data from an image.", - "

", - "EXIF data is metadata embedded in images (JPEG, JPG, TIFF) and audio files.", - "

", - "EXIF data from photos usually contains information about the image file itself as well as the device used to create it.", - ].join("\n"), - inputType: "ArrayBuffer", - outputType: "string", - args: [], - }, - "Render Image": { - module: "Image", - description: "Displays the input as an image. Supports the following formats:

  • jpg/jpeg
  • png
  • gif
  • webp
  • bmp
  • ico
", - inputType: "string", - outputType: "html", - args: [ - { - name: "Input format", - type: "option", - value: "Image.INPUT_FORMAT" - } - ], - patterns: [ - { - match: "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)", - flags: "", - args: ["Raw"], - useful: true - }, - ] - }, - "Remove EXIF": { - module: "Image", - description: [ - "Removes EXIF data from a JPEG image.", - "

", - "EXIF data embedded in photos usually contains information about the image file itself as well as the device used to create it.", - ].join("\n"), - inputType: "byteArray", - outputType: "byteArray", - args: [] - }, - "HTTP request": { - module: "HTTP", - description: [ - "Makes an HTTP request and returns the response.", - "

", - "This operation supports different HTTP verbs like GET, POST, PUT, etc.", - "

", - "You can add headers line by line in the format Key: Value", - "

", - "The status code of the response, along with a limited selection of exposed headers, can be viewed by checking the 'Show response metadata' option. Only a limited set of response headers are exposed by the browser for security reasons.", - ].join("\n"), - inputType: "string", - outputType: "string", - manualBake: true, - args: [ - { - name: "Method", - type: "option", - value: "HTTP.METHODS," - }, - { - name: "URL", - type: "string", - value: "", - }, - { - name: "Headers", - type: "text", - value: "", - }, - { - name: "Mode", - type: "option", - value: "HTTP.MODE," - }, - { - name: "Show response metadata", - type: "boolean", - value: false, - } - ] - }, - "From BCD": { - module: "Default", - description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign.", - inputType: "string", - outputType: "BigNumber", - args: [ - { - name: "Scheme", - type: "option", - value: "BCD.ENCODING_SCHEME" - }, - { - name: "Packed", - type: "boolean", - value: true - }, - { - name: "Signed", - type: "boolean", - value: false - }, - { - name: "Input format", - type: "option", - value: "BCD.FORMAT" - } - ], - patterns: [ - { - match: "^(?:\\d{4} ){3,}\\d{4}$", - flags: "", - args: ["8 4 2 1", true, false, "Nibbles"] - }, - ] - }, - "To BCD": { - module: "Default", - description: "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign", - inputType: "BigNumber", - outputType: "string", - args: [ - { - name: "Scheme", - type: "option", - value: "BCD.ENCODING_SCHEME" - }, - { - name: "Packed", - type: "boolean", - value: true - }, - { - name: "Signed", - type: "boolean", - value: false - }, - { - name: "Output format", - type: "option", - value: "BCD.FORMAT" - } - ] - - }, - "Bit shift left": { - module: "Default", - description: "Shifts the bits in each byte towards the left by the specified amount.", - inputType: "byteArray", - outputType: "byteArray", - highlight: true, - highlightReverse: true, - args: [ - { - name: "Amount", - type: "number", - value: 1 - }, - ] - }, - "Bit shift right": { - module: "Default", - description: "Shifts the bits in each byte towards the right by the specified amount.

Logical shifts replace the leftmost bits with zeros.
Arithmetic shifts preserve the most significant bit (MSB) of the original byte keeping the sign the same (positive or negative).", - inputType: "byteArray", - outputType: "byteArray", - highlight: true, - highlightReverse: true, - args: [ - { - name: "Amount", - type: "number", - value: 1 - }, - { - name: "Type", - type: "option", - value: "BitwiseOp.BIT_SHIFT_TYPE" - } - ] - }, - "Generate TOTP": { - module: "Default", - description: "The Time-based One-Time Password algorithm (TOTP) is an algorithm that computes a one-time password from a shared secret key and the current time. It has been adopted as Internet Engineering Task Force standard RFC 6238, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems. A TOTP is an HOTP where the counter is the current time.

Enter the secret as the input or leave it blank for a random secret to be generated. T0 and T1 are in seconds.", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Name", - type: "string", - value: "" - }, - { - name: "Key size", - type: "number", - value: 32 - }, - { - name: "Code length", - type: "number", - value: 6 - }, - { - name: "Epoch offset (T0)", - type: "number", - value: 0 - }, - { - name: "Interval (T1)", - type: "number", - value: 30 - } - ] - }, - "Generate HOTP": { - module: "Default", - description: "The HMAC-based One-Time Password algorithm (HOTP) is an algorithm that computes a one-time password from a shared secret key and an incrementing counter. It has been adopted as Internet Engineering Task Force standard RFC 4226, is the cornerstone of Initiative For Open Authentication (OATH), and is used in a number of two-factor authentication systems.

Enter the secret as the input or leave it blank for a random secret to be generated.", - inputType: "byteArray", - outputType: "string", - args: [ - { - name: "Name", - type: "string", - value: "" - }, - { - name: "Key size", - type: "number", - value: 32 - }, - { - name: "Code length", - type: "number", - value: 6 - }, - { - name: "Counter", - type: "number", - value: 0 - } - ] - }, - "PHP Deserialize": { - module: "Default", - description: "Deserializes PHP serialized data, outputting keyed arrays as JSON.

This function does not support object tags.

Example:
a:2:{s:1:"a";i:10;i:0;a:1:{s:2:"ab";b:1;}}
becomes
{"a": 10,0: {"ab": true}}

Output valid JSON: JSON doesn't support integers as keys, whereas PHP serialization does. Enabling this will cast these integers to strings. This will also escape backslashes.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Output valid JSON", - type: "boolean", - value: "PHP.OUTPUT_VALID_JSON" - } - ] - }, - "Hamming Distance": { - module: "Default", - description: "In information theory, the Hamming distance between two strings of equal length is the number of positions at which the corresponding symbols are different. In other words, it measures the minimum number of substitutions required to change one string into the other, or the minimum number of errors that could have transformed one string into the other. In a more general context, the Hamming distance is one of several string metrics for measuring the edit distance between two sequences.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Delimiter", - type: "binaryShortString", - value: "StrUtils.HAMMING_DELIM" - }, - { - name: "Unit", - type: "option", - value: "StrUtils.HAMMING_UNIT" - }, - { - name: "Input type", - type: "option", - value: "StrUtils.HAMMING_INPUT_TYPE" - } - ] - }, - "XKCD Random Number": { - module: "Default", - description: "RFC 1149.5 specifies 4 as the standard IEEE-vetted random number.

XKCD #221", - inputType: "string", - outputType: "number", - args: [] - }, - "Bcrypt": { - module: "Hashing", - description: "bcrypt is a password hashing function designed by Niels Provos and David Mazières, based on the Blowfish cipher, and presented at USENIX in 1999. Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the iteration count (rounds) can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power.

Enter the password in the input to generate its hash.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Rounds", - type: "number", - value: "Hash.BCRYPT_ROUNDS" - } - ] - }, - "Bcrypt compare": { - module: "Hashing", - description: "Tests whether the input matches the given bcrypt hash. To test multiple possible passwords, use the 'Fork' operation.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Hash", - type: "string", - value: "" - } - ] - }, - "Bcrypt parse": { - module: "Hashing", - description: "Parses a bcrypt hash to determine the number of rounds used, the salt, and the password hash.", - inputType: "string", - outputType: "string", - args: [] - }, - "Scrypt": { - module: "Hashing", - description: "scrypt is a password-based key derivation function (PBKDF) created by Colin Percival. The algorithm was specifically designed to make it costly to perform large-scale custom hardware attacks by requiring large amounts of memory. In 2016, the scrypt algorithm was published by IETF as RFC 7914.

Enter the password in the input to generate its hash.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Salt", - type: "toggleString", - value: "", - toggleValues: "Hash.KEY_FORMAT" - }, - { - name: "Iterations (N)", - type: "number", - value: "Hash.SCRYPT_ITERATIONS" - }, - { - name: "Memory factor (r)", - type: "number", - value: "Hash.SCRYPT_MEM_FACTOR" - }, - { - name: "Parallelization factor (p)", - type: "number", - value: "Hash.SCRYPT_PARALLEL_FACTOR" - }, - { - name: "Key length", - type: "number", - value: "Hash.SCRYPT_KEY_LENGTH" - }, - ] - }, - "BSON serialise": { - module: "BSON", - description: "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.

Input data should be valid JSON.", - inputType: "string", - outputType: "ArrayBuffer", - args: [] - }, - "BSON deserialise": { - module: "BSON", - description: "BSON is a computer data interchange format used mainly as a data storage and network transfer format in the MongoDB database. It is a binary form for representing simple data structures, associative arrays (called objects or documents in MongoDB), and various data types of specific interest to MongoDB. The name 'BSON' is based on the term JSON and stands for 'Binary JSON'.

Input data should be in a raw bytes format.", - inputType: "ArrayBuffer", - outputType: "string", - args: [] - }, - "Generate PGP Key Pair": { - module: "PGP", - description: "Generates a new public/private PGP key pair. Supports RSA and Eliptic Curve (EC) keys.", - inputType: "string", - outputType: "string", - args: [ - { - name: "Key type", - type: "option", - value: "PGP.KEY_TYPES" - }, - { - name: "Password (optional)", - type: "string", - value: "" - }, - { - name: "Name (optional)", - type: "string", - value: "" - }, - { - name: "Email (optional)", - type: "string", - value: "" - }, - ] - }, - "PGP Encrypt": { - module: "PGP", - description: [ - "Input: the message you want to encrypt.", - "

", - "Arguments: the ASCII-armoured PGP public key of the recipient.", - "

", - "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", - "

", - "This function uses the Keybase implementation of PGP.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Public key of recipient", - type: "text", - value: "" - }, - ] - }, - "PGP Decrypt": { - module: "PGP", - description: [ - "Input: the ASCII-armoured PGP message you want to decrypt.", - "

", - "Arguments: the ASCII-armoured PGP private key of the recipient, ", - "(and the private key password if necessary).", - "

", - "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", - "

", - "This function uses the Keybase implementation of PGP.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Private key of recipient", - type: "text", - value: "" - }, - { - name: "Private key passphrase", - type: "string", - value: "" - }, - ] - }, - "PGP Encrypt and Sign": { - module: "PGP", - description: [ - "Input: the cleartext you want to sign.", - "

", - "Arguments: the ASCII-armoured private key of the signer (plus the private key password if necessary)", - "and the ASCII-armoured PGP public key of the recipient.", - "

", - "This operation uses PGP to produce an encrypted digital signature.", - "

", - "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", - "

", - "This function uses the Keybase implementation of PGP.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Private key of signer", - type: "text", - value: "" - }, - { - name: "Private key passphrase", - type: "string", - value: "" - }, - { - name: "Public key of recipient", - type: "text", - value: "" - }, - ] - }, - "PGP Decrypt and Verify": { - module: "PGP", - description: [ - "Input: the ASCII-armoured encrypted PGP message you want to verify.", - "

", - "Arguments: the ASCII-armoured PGP public key of the signer, ", - "the ASCII-armoured private key of the recipient (and the private key password if necessary).", - "

", - "This operation uses PGP to decrypt and verify an encrypted digital signature.", - "

", - "Pretty Good Privacy is an encryption standard (OpenPGP) used for encrypting, decrypting, and signing messages.", - "

", - "This function uses the Keybase implementation of PGP.", - ].join("\n"), - inputType: "string", - outputType: "string", - args: [ - { - name: "Public key of signer", - type: "text", - value: "", - }, - { - name: "Private key of recipient", - type: "text", - value: "", - }, - { - name: "Private key password", - type: "string", - value: "", - }, - ] - }, -}; - -main(); diff --git a/src/core/operations/legacy/Arithmetic.js b/src/core/operations/legacy/Arithmetic.js deleted file mode 100644 index e1e44981..00000000 --- a/src/core/operations/legacy/Arithmetic.js +++ /dev/null @@ -1,259 +0,0 @@ -/** - * @author d98762625 [d98762625@gmail.com] - * @copyright Crown Copyright 2018 - * @license Apache-2.0 - */ - -import Utils from "../Utils.js"; -import BigNumber from "bignumber.js"; - - -/** - * Math operations on numbers. - * - * @author bwhitn [brian.m.whitney@outlook.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Arithmetic = { - - /** - * @constant - * @default - */ - DELIM_OPTIONS: ["Line feed", "Space", "Comma", "Semi-colon", "Colon", "CRLF"], - - - /** - * Splits a string based on a delimiter and calculates the sum of numbers. - * - * @param {string} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runSum: function(input, args) { - const val = Arithmetic._sum(Arithmetic._createNumArray(input, args[0])); - return val instanceof BigNumber ? val : new BigNumber(NaN); - }, - - - /** - * Splits a string based on a delimiter and subtracts all the numbers. - * - * @param {string} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runSub: function(input, args) { - let val = Arithmetic._sub(Arithmetic._createNumArray(input, args[0])); - return val instanceof BigNumber ? val : new BigNumber(NaN); - }, - - - /** - * Splits a string based on a delimiter and multiplies the numbers. - * - * @param {string} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runMulti: function(input, args) { - let val = Arithmetic._multi(Arithmetic._createNumArray(input, args[0])); - return val instanceof BigNumber ? val : new BigNumber(NaN); - }, - - - /** - * Splits a string based on a delimiter and divides the numbers. - * - * @param {string} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runDiv: function(input, args) { - let val = Arithmetic._div(Arithmetic._createNumArray(input, args[0])); - return val instanceof BigNumber ? val : new BigNumber(NaN); - }, - - - /** - * Splits a string based on a delimiter and computes the mean (average). - * - * @param {string} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runMean: function(input, args) { - let val = Arithmetic._mean(Arithmetic._createNumArray(input, args[0])); - return val instanceof BigNumber ? val : new BigNumber(NaN); - }, - - - /** - * Splits a string based on a delimiter and finds the median. - * - * @param {string} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runMedian: function(input, args) { - let val = Arithmetic._median(Arithmetic._createNumArray(input, args[0])); - return val instanceof BigNumber ? val : new BigNumber(NaN); - }, - - - /** - * splits a string based on a delimiter and computes the standard deviation. - * - * @param {string} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runStdDev: function(input, args) { - let val = Arithmetic._stdDev(Arithmetic._createNumArray(input, args[0])); - return val instanceof BigNumber ? val : new BigNumber(NaN); - }, - - - /** - * Converts a string array to a number array. - * - * @private - * @param {string[]} input - * @param {string} delim - * @returns {BigNumber[]} - */ - _createNumArray: function(input, delim) { - delim = Utils.charRep(delim || "Space"); - let splitNumbers = input.split(delim), - numbers = [], - num; - - for (let i = 0; i < splitNumbers.length; i++) { - try { - num = BigNumber(splitNumbers[i].trim()); - if (!num.isNaN()) { - numbers.push(num); - } - } catch (err) { - // This line is not a valid number - } - } - return numbers; - }, - - - /** - * Adds an array of numbers and returns the value. - * - * @private - * @param {BigNumber[]} data - * @returns {BigNumber} - */ - _sum: function(data) { - if (data.length > 0) { - return data.reduce((acc, curr) => acc.plus(curr)); - } - }, - - - /** - * Subtracts an array of numbers and returns the value. - * - * @private - * @param {BigNumber[]} data - * @returns {BigNumber} - */ - _sub: function(data) { - if (data.length > 0) { - return data.reduce((acc, curr) => acc.minus(curr)); - } - }, - - - /** - * Multiplies an array of numbers and returns the value. - * - * @private - * @param {BigNumber[]} data - * @returns {BigNumber} - */ - _multi: function(data) { - if (data.length > 0) { - return data.reduce((acc, curr) => acc.times(curr)); - } - }, - - - /** - * Divides an array of numbers and returns the value. - * - * @private - * @param {BigNumber[]} data - * @returns {BigNumber} - */ - _div: function(data) { - if (data.length > 0) { - return data.reduce((acc, curr) => acc.div(curr)); - } - }, - - - /** - * Computes mean of a number array and returns the value. - * - * @private - * @param {BigNumber[]} data - * @returns {BigNumber} - */ - _mean: function(data) { - if (data.length > 0) { - return Arithmetic._sum(data).div(data.length); - } - }, - - - /** - * Computes median of a number array and returns the value. - * - * @private - * @param {BigNumber[]} data - * @returns {BigNumber} - */ - _median: function (data) { - if ((data.length % 2) === 0 && data.length > 0) { - let first, second; - data.sort(function(a, b){ - return a.minus(b); - }); - first = data[Math.floor(data.length / 2)]; - second = data[Math.floor(data.length / 2) - 1]; - return Arithmetic._mean([first, second]); - } else { - return data[Math.floor(data.length / 2)]; - } - }, - - - /** - * Computes standard deviation of a number array and returns the value. - * - * @private - * @param {BigNumber[]} data - * @returns {BigNumber} - */ - _stdDev: function (data) { - if (data.length > 0) { - let avg = Arithmetic._mean(data); - let devSum = new BigNumber(0); - for (let i = 0; i < data.length; i++) { - devSum = devSum.plus(data[i].minus(avg).pow(2)); - } - return devSum.div(data.length).sqrt(); - } - }, -}; - -export default Arithmetic; diff --git a/src/core/operations/legacy/BCD.js b/src/core/operations/legacy/BCD.js deleted file mode 100755 index ee20f2df..00000000 --- a/src/core/operations/legacy/BCD.js +++ /dev/null @@ -1,215 +0,0 @@ -import Utils from "../Utils.js"; -import BigNumber from "bignumber.js"; - - -/** - * Binary-Coded Decimal operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2017 - * @license Apache-2.0 - * - * @namespace - */ -const BCD = { - - /** - * @constant - * @default - */ - ENCODING_SCHEME: [ - "8 4 2 1", - "7 4 2 1", - "4 2 2 1", - "2 4 2 1", - "8 4 -2 -1", - "Excess-3", - "IBM 8 4 2 1", - ], - - /** - * Lookup table for the binary value of each digit representation. - * - * I wrote a very nice algorithm to generate 8 4 2 1 encoding programatically, - * but unfortunately it's much easier (if less elegant) to use lookup tables - * when supporting multiple encoding schemes. - * - * "Practicality beats purity" - PEP 20 - * - * In some schemes it is possible to represent the same value in multiple ways. - * For instance, in 4 2 2 1 encoding, 0100 and 0010 both represent 2. Support - * has not yet been added for this. - * - * @constant - */ - ENCODING_LOOKUP: { - "8 4 2 1": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], - "7 4 2 1": [0, 1, 2, 3, 4, 5, 6, 8, 9, 10], - "4 2 2 1": [0, 1, 4, 5, 8, 9, 12, 13, 14, 15], - "2 4 2 1": [0, 1, 2, 3, 4, 11, 12, 13, 14, 15], - "8 4 -2 -1": [0, 7, 6, 5, 4, 11, 10, 9, 8, 15], - "Excess-3": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12], - "IBM 8 4 2 1": [10, 1, 2, 3, 4, 5, 6, 7, 8, 9], - }, - - /** - * @default - * @constant - */ - FORMAT: ["Nibbles", "Bytes", "Raw"], - - - /** - * To BCD operation. - * - * @param {BigNumber} input - * @param {Object[]} args - * @returns {string} - */ - runToBCD: function(input, args) { - if (input.isNaN()) - return "Invalid input"; - if (!input.integerValue(BigNumber.ROUND_DOWN).isEqualTo(input)) - return "Fractional values are not supported by BCD"; - - const encoding = BCD.ENCODING_LOOKUP[args[0]], - packed = args[1], - signed = args[2], - outputFormat = args[3]; - - // Split input number up into separate digits - const digits = input.toFixed().split(""); - - if (digits[0] === "-" || digits[0] === "+") { - digits.shift(); - } - - let nibbles = []; - - digits.forEach(d => { - const n = parseInt(d, 10); - nibbles.push(encoding[n]); - }); - - if (signed) { - if (packed && digits.length % 2 === 0) { - // If there are an even number of digits, we add a leading 0 so - // that the sign nibble doesn't sit in its own byte, leading to - // ambiguity around whether the number ends with a 0 or not. - nibbles.unshift(encoding[0]); - } - - nibbles.push(input > 0 ? 12 : 13); - // 12 ("C") for + (credit) - // 13 ("D") for - (debit) - } - - let bytes = []; - - if (packed) { - let encoded = 0, - little = false; - - nibbles.forEach(n => { - encoded ^= little ? n : (n << 4); - if (little) { - bytes.push(encoded); - encoded = 0; - } - little = !little; - }); - - if (little) bytes.push(encoded); - } else { - bytes = nibbles; - - // Add null high nibbles - nibbles = nibbles.map(n => { - return [0, n]; - }).reduce((a, b) => { - return a.concat(b); - }); - } - - // Output - switch (outputFormat) { - case "Nibbles": - return nibbles.map(n => { - return n.toString(2).padStart(4, "0"); - }).join(" "); - case "Bytes": - return bytes.map(b => { - return b.toString(2).padStart(8, "0"); - }).join(" "); - case "Raw": - default: - return Utils.byteArrayToChars(bytes); - } - }, - - - /** - * From BCD operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runFromBCD: function(input, args) { - const encoding = BCD.ENCODING_LOOKUP[args[0]], - packed = args[1], - signed = args[2], - inputFormat = args[3]; - - let nibbles = [], - output = "", - byteArray; - - // Normalise the input - switch (inputFormat) { - case "Nibbles": - case "Bytes": - input = input.replace(/\s/g, ""); - for (let i = 0; i < input.length; i += 4) { - nibbles.push(parseInt(input.substr(i, 4), 2)); - } - break; - case "Raw": - default: - byteArray = Utils.strToByteArray(input); - byteArray.forEach(b => { - nibbles.push(b >>> 4); - nibbles.push(b & 15); - }); - break; - } - - if (!packed) { - // Discard each high nibble - for (let i = 0; i < nibbles.length; i++) { - nibbles.splice(i, 1); - } - } - - if (signed) { - const sign = nibbles.pop(); - if (sign === 13 || - sign === 11) { - // Negative - output += "-"; - } - } - - nibbles.forEach(n => { - if (isNaN(n)) throw "Invalid input"; - let val = encoding.indexOf(n); - if (val < 0) throw `Value ${Utils.bin(n, 4)} not in encoding scheme`; - output += val.toString(); - }); - - return new BigNumber(output); - }, - -}; - -export default BCD; diff --git a/src/core/operations/legacy/BSON.js b/src/core/operations/legacy/BSON.js deleted file mode 100644 index 4f0d484f..00000000 --- a/src/core/operations/legacy/BSON.js +++ /dev/null @@ -1,59 +0,0 @@ -import bsonjs from "bson"; -import {Buffer} from "buffer"; - - -/** - * BSON operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2018 - * @license Apache-2.0 - * - * @namespace - */ -const BSON = { - - /** - * BSON serialise operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {ArrayBuffer} - */ - runBSONSerialise(input, args) { - if (!input) return new ArrayBuffer(); - - const bson = new bsonjs(); - - try { - const data = JSON.parse(input); - return bson.serialize(data).buffer; - } catch (err) { - throw err.toString(); - } - }, - - - /** - * BSON deserialise operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - * - */ - runBSONDeserialise(input, args) { - if (!input.byteLength) return ""; - - const bson = new bsonjs(); - - try { - const data = bson.deserialize(new Buffer(input)); - return JSON.stringify(data, null, 2); - } catch (err) { - return err.toString(); - } - }, -}; - -export default BSON; diff --git a/src/core/operations/legacy/Base.js b/src/core/operations/legacy/Base.js deleted file mode 100755 index 06bbeb7c..00000000 --- a/src/core/operations/legacy/Base.js +++ /dev/null @@ -1,68 +0,0 @@ -import BigNumber from "bignumber.js"; - -/** - * Numerical base operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Base = { - - /** - * @constant - * @default - */ - DEFAULT_RADIX: 36, - - /** - * To Base operation. - * - * @param {BigNumber} input - * @param {Object[]} args - * @returns {string} - */ - runTo: function(input, args) { - if (!input) { - throw ("Error: Input must be a number"); - } - const radix = args[0] || Base.DEFAULT_RADIX; - if (radix < 2 || radix > 36) { - throw "Error: Radix argument must be between 2 and 36"; - } - return input.toString(radix); - }, - - - /** - * From Base operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runFrom: function(input, args) { - const radix = args[0] || Base.DEFAULT_RADIX; - if (radix < 2 || radix > 36) { - throw "Error: Radix argument must be between 2 and 36"; - } - - let number = input.replace(/\s/g, "").split("."), - result = new BigNumber(number[0], radix) || 0; - - if (number.length === 1) return result; - - // Fractional part - for (let i = 0; i < number[1].length; i++) { - const digit = new BigNumber(number[1][i], radix); - result += digit.div(Math.pow(radix, i+1)); - } - - return result; - }, - -}; - -export default Base; diff --git a/src/core/operations/legacy/Base58.js b/src/core/operations/legacy/Base58.js deleted file mode 100755 index 2eabf1da..00000000 --- a/src/core/operations/legacy/Base58.js +++ /dev/null @@ -1,137 +0,0 @@ -import Utils from "../Utils.js"; - - -/** - * Base58 operations. - * - * @author tlwr [toby@toby.codes] - * @copyright Crown Copyright 2017 - * @license Apache-2.0 - * - * @namespace - */ -const 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) { - let alphabet = args[0] || Base58.ALPHABET_OPTIONS[0].value, - result = [0]; - - alphabet = Utils.expandAlphRange(alphabet).join(""); - - if (alphabet.length !== 58 || - [].unique.call(alphabet).length !== 58) { - throw ("Error: alphabet must be of length 58"); - } - - if (input.length === 0) return ""; - - input.forEach(function(b) { - let carry = (result[0] << 8) + b; - result[0] = carry % 58; - carry = (carry / 58) | 0; - - for (let 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) { - let alphabet = args[0] || Base58.ALPHABET_OPTIONS[0].value, - removeNonAlphaChars = args[1] === undefined ? true : args[1], - result = [0]; - - alphabet = Utils.expandAlphRange(alphabet).join(""); - - if (alphabet.length !== 58 || - [].unique.call(alphabet).length !== 58) { - throw ("Alphabet must be of length 58"); - } - - if (input.length === 0) return []; - - [].forEach.call(input, function(c, charIndex) { - const index = alphabet.indexOf(c); - - if (index === -1) { - if (removeNonAlphaChars) { - return; - } else { - throw ("Char '" + c + "' at position " + charIndex + " not in alphabet"); - } - } - - let carry = result[0] * 58 + index; - result[0] = carry & 0xFF; - carry = carry >> 8; - - for (let 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(); - }, - -}; - -export default Base58; diff --git a/src/core/operations/legacy/ByteRepr.js b/src/core/operations/legacy/ByteRepr.js deleted file mode 100755 index 548db525..00000000 --- a/src/core/operations/legacy/ByteRepr.js +++ /dev/null @@ -1,355 +0,0 @@ -import Utils from "../Utils.js"; -import {toHex, fromHex} from "../lib/Hex"; - - -/** - * Byte representation operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const ByteRepr = { - - /** - * @constant - * @default - */ - DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF"], - /** - * @constant - * @default - */ - TO_HEX_DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"], - /** - * @constant - * @default - */ - FROM_HEX_DELIM_OPTIONS: ["Auto", "Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"], - /** - * @constant - * @default - */ - BIN_DELIM_OPTIONS: ["Space", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "None"], - - - /** - * To Octal operation. - * - * @author Matt C [matt@artemisbot.uk] - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runToOct: function(input, args) { - const delim = Utils.charRep(args[0] || "Space"); - return input.map(val => val.toString(8)).join(delim); - }, - - - /** - * From Octal operation. - * - * @author Matt C [matt@artemisbot.uk] - * @param {string} input - * @param {Object[]} args - * @returns {byteArray} - */ - runFromOct: function(input, args) { - const delim = Utils.charRep(args[0] || "Space"); - if (input.length === 0) return []; - return input.split(delim).map(val => parseInt(val, 8)); - }, - - - /** - * @constant - * @default - */ - CHARCODE_BASE: 16, - - /** - * To Charcode operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runToCharcode: function(input, args) { - let delim = Utils.charRep(args[0] || "Space"), - base = args[1], - output = "", - padding = 2, - ordinal; - - if (base < 2 || base > 36) { - throw "Error: Base argument must be between 2 and 36"; - } - - const charcode = Utils.strToCharcode(input); - for (let i = 0; i < charcode.length; i++) { - ordinal = charcode[i]; - - if (base === 16) { - if (ordinal < 256) padding = 2; - else if (ordinal < 65536) padding = 4; - else if (ordinal < 16777216) padding = 6; - else if (ordinal < 4294967296) padding = 8; - else padding = 2; - - if (padding > 2 && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false); - - output += Utils.hex(ordinal, padding) + delim; - } else { - if (ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false); - output += ordinal.toString(base) + delim; - } - } - - return output.slice(0, -delim.length); - }, - - - /** - * From Charcode operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {byteArray} - */ - runFromCharcode: function(input, args) { - let delim = Utils.charRep(args[0] || "Space"), - base = args[1], - bites = input.split(delim), - i = 0; - - if (base < 2 || base > 36) { - throw "Error: Base argument must be between 2 and 36"; - } - - if (input.length === 0) { - return []; - } - - if (base !== 16 && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false); - - // Split into groups of 2 if the whole string is concatenated and - // too long to be a single character - if (bites.length === 1 && input.length > 17) { - bites = []; - for (i = 0; i < input.length; i += 2) { - bites.push(input.slice(i, i+2)); - } - } - - let latin1 = ""; - for (i = 0; i < bites.length; i++) { - latin1 += Utils.chr(parseInt(bites[i], base)); - } - return Utils.strToByteArray(latin1); - }, - - - /** - * To Decimal operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runToDecimal: function(input, args) { - const delim = Utils.charRep(args[0]); - return input.join(delim); - }, - - - /** - * From Decimal operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {byteArray} - */ - runFromDecimal: function(input, args) { - const delim = Utils.charRep(args[0]); - let byteStr = input.split(delim), output = []; - if (byteStr[byteStr.length-1] === "") - byteStr = byteStr.slice(0, byteStr.length-1); - - for (let i = 0; i < byteStr.length; i++) { - output[i] = parseInt(byteStr[i], 10); - } - return output; - }, - - - /** - * To Binary operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runToBinary: function(input, args) { - let delim = Utils.charRep(args[0] || "Space"), - output = "", - padding = 8; - - for (let i = 0; i < input.length; i++) { - output += input[i].toString(2).padStart(padding, "0") + delim; - } - - if (delim.length) { - return output.slice(0, -delim.length); - } else { - return output; - } - }, - - - /** - * From Binary operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {byteArray} - */ - runFromBinary: function(input, args) { - const delimRegex = Utils.regexRep(args[0] || "Space"); - input = input.replace(delimRegex, ""); - - const output = []; - const byteLen = 8; - for (let i = 0; i < input.length; i += byteLen) { - output.push(parseInt(input.substr(i, byteLen), 2)); - } - return output; - }, - - - /** - * Highlight to binary - * - * @param {Object[]} pos - * @param {number} pos[].start - * @param {number} pos[].end - * @param {Object[]} args - * @returns {Object[]} pos - */ - highlightToBinary: function(pos, args) { - const delim = Utils.charRep(args[0] || "Space"); - pos[0].start = pos[0].start * (8 + delim.length); - pos[0].end = pos[0].end * (8 + delim.length) - delim.length; - return pos; - }, - - - /** - * Highlight from binary - * - * @param {Object[]} pos - * @param {number} pos[].start - * @param {number} pos[].end - * @param {Object[]} args - * @returns {Object[]} pos - */ - highlightFromBinary: function(pos, args) { - const delim = Utils.charRep(args[0] || "Space"); - pos[0].start = pos[0].start === 0 ? 0 : Math.floor(pos[0].start / (8 + delim.length)); - pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / (8 + delim.length)); - return pos; - }, - - - /** - * @constant - * @default - */ - HEX_CONTENT_CONVERT_WHICH: ["Only special chars", "Only special chars including spaces", "All chars"], - /** - * @constant - * @default - */ - HEX_CONTENT_SPACES_BETWEEN_BYTES: false, - - /** - * To Hex Content operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runToHexContent: function(input, args) { - const convert = args[0]; - const spaces = args[1]; - if (convert === "All chars") { - let result = "|" + toHex(input) + "|"; - if (!spaces) result = result.replace(/ /g, ""); - return result; - } - - let output = "", - inHex = false, - convertSpaces = convert === "Only special chars including spaces", - b; - for (let i = 0; i < input.length; i++) { - b = input[i]; - if ((b === 32 && convertSpaces) || (b < 48 && b !== 32) || (b > 57 && b < 65) || (b > 90 && b < 97) || b > 122) { - if (!inHex) { - output += "|"; - inHex = true; - } else if (spaces) output += " "; - output += toHex([b]); - } else { - if (inHex) { - output += "|"; - inHex = false; - } - output += Utils.chr(input[i]); - } - } - if (inHex) output += "|"; - return output; - }, - - - /** - * From Hex Content operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {byteArray} - */ - runFromHexContent: function(input, args) { - const regex = /\|([a-f\d ]{2,})\|/gi; - let output = [], m, i = 0; - while ((m = regex.exec(input))) { - // Add up to match - for (; i < m.index;) - output.push(Utils.ord(input[i++])); - - // Add match - const bytes = fromHex(m[1]); - if (bytes) { - for (let a = 0; a < bytes.length;) - output.push(bytes[a++]); - } else { - // Not valid hex, print as normal - for (; i < regex.lastIndex;) - output.push(Utils.ord(input[i++])); - } - - i = regex.lastIndex; - } - // Add all after final match - for (; i < input.length;) - output.push(Utils.ord(input[i++])); - - return output; - }, - -}; - -export default ByteRepr; diff --git a/src/core/operations/legacy/CharEnc.js b/src/core/operations/legacy/CharEnc.js deleted file mode 100755 index 6b509e1e..00000000 --- a/src/core/operations/legacy/CharEnc.js +++ /dev/null @@ -1,97 +0,0 @@ -import cptable from "../vendor/js-codepage/cptable.js"; - - -/** - * Character encoding operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const CharEnc = { - - /** - * @constant - * @default - */ - IO_FORMAT: { - "UTF-8 (65001)": 65001, - "UTF-7 (65000)": 65000, - "UTF16LE (1200)": 1200, - "UTF16BE (1201)": 1201, - "UTF16 (1201)": 1201, - "IBM EBCDIC International (500)": 500, - "IBM EBCDIC US-Canada (37)": 37, - "Windows-874 Thai (874)": 874, - "Japanese Shift-JIS (932)": 932, - "Simplified Chinese GBK (936)": 936, - "Korean (949)": 949, - "Traditional Chinese Big5 (950)": 950, - "Windows-1250 Central European (1250)": 1250, - "Windows-1251 Cyrillic (1251)": 1251, - "Windows-1252 Latin (1252)": 1252, - "Windows-1253 Greek (1253)": 1253, - "Windows-1254 Turkish (1254)": 1254, - "Windows-1255 Hebrew (1255)": 1255, - "Windows-1256 Arabic (1256)": 1256, - "Windows-1257 Baltic (1257)": 1257, - "Windows-1258 Vietnam (1258)": 1258, - "US-ASCII (20127)": 20127, - "Simplified Chinese GB2312 (20936)": 20936, - "KOI8-R Russian Cyrillic (20866)": 20866, - "KOI8-U Ukrainian Cyrillic (21866)": 21866, - "ISO-8859-1 Latin 1 Western European (28591)": 28591, - "ISO-8859-2 Latin 2 Central European (28592)": 28592, - "ISO-8859-3 Latin 3 South European (28593)": 28593, - "ISO-8859-4 Latin 4 North European (28594)": 28594, - "ISO-8859-5 Latin/Cyrillic (28595)": 28595, - "ISO-8859-6 Latin/Arabic (28596)": 28596, - "ISO-8859-7 Latin/Greek (28597)": 28597, - "ISO-8859-8 Latin/Hebrew (28598)": 28598, - "ISO-8859-9 Latin 5 Turkish (28599)": 28599, - "ISO-8859-10 Latin 6 Nordic (28600)": 28600, - "ISO-8859-11 Latin/Thai (28601)": 28601, - "ISO-8859-13 Latin 7 Baltic Rim (28603)": 28603, - "ISO-8859-14 Latin 8 Celtic (28604)": 28604, - "ISO-8859-15 Latin 9 (28605)": 28605, - "ISO-8859-16 Latin 10 (28606)": 28606, - "ISO-2022 JIS Japanese (50222)": 50222, - "EUC Japanese (51932)": 51932, - "EUC Korean (51949)": 51949, - "Simplified Chinese GB18030 (54936)": 54936, - }, - - /** - * Encode text operation. - * @author tlwr [toby@toby.codes] - * - * @param {string} input - * @param {Object[]} args - * @returns {byteArray} - */ - runEncode: function(input, args) { - const format = CharEnc.IO_FORMAT[args[0]]; - let encoded = cptable.utils.encode(format, input); - encoded = Array.from(encoded); - return encoded; - }, - - - /** - * Decode text operation. - * @author tlwr [toby@toby.codes] - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runDecode: function(input, args) { - const format = CharEnc.IO_FORMAT[args[0]]; - let decoded = cptable.utils.decode(format, input); - return decoded; - }, -}; - -export default CharEnc; diff --git a/src/core/operations/legacy/Checksum.js b/src/core/operations/legacy/Checksum.js deleted file mode 100755 index 6b2cb31c..00000000 --- a/src/core/operations/legacy/Checksum.js +++ /dev/null @@ -1,179 +0,0 @@ -import * as CRC from "js-crc"; -import Utils from "../Utils.js"; - - -/** - * Checksum operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Checksum = { - - /** - * Fletcher-8 Checksum operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runFletcher8: function(input, args) { - let a = 0, - b = 0; - - for (let i = 0; i < input.length; i++) { - a = (a + input[i]) % 0xf; - b = (b + a) % 0xf; - } - - return Utils.hex(((b << 4) | a) >>> 0, 2); - }, - - - /** - * Fletcher-16 Checksum operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runFletcher16: function(input, args) { - let a = 0, - b = 0; - - for (let i = 0; i < input.length; i++) { - a = (a + input[i]) % 0xff; - b = (b + a) % 0xff; - } - - return Utils.hex(((b << 8) | a) >>> 0, 4); - }, - - - /** - * Fletcher-32 Checksum operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runFletcher32: function(input, args) { - let a = 0, - b = 0; - - for (let i = 0; i < input.length; i++) { - a = (a + input[i]) % 0xffff; - b = (b + a) % 0xffff; - } - - return Utils.hex(((b << 16) | a) >>> 0, 8); - }, - - - /** - * Fletcher-64 Checksum operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runFletcher64: function(input, args) { - let a = 0, - b = 0; - - for (let i = 0; i < input.length; i++) { - a = (a + input[i]) % 0xffffffff; - b = (b + a) % 0xffffffff; - } - - return Utils.hex(b >>> 0, 8) + Utils.hex(a >>> 0, 8); - }, - - - /** - * Adler-32 Checksum operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runAdler32: function(input, args) { - let MOD_ADLER = 65521, - a = 1, - b = 0; - - for (let i = 0; i < input.length; i++) { - a += input[i]; - b += a; - } - - a %= MOD_ADLER; - b %= MOD_ADLER; - - return Utils.hex(((b << 16) | a) >>> 0, 8); - }, - - - /** - * CRC-32 Checksum operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runCRC32: function(input, args) { - return CRC.crc32(input); - }, - - - /** - * CRC-16 Checksum operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runCRC16: function(input, args) { - return CRC.crc16(input); - }, - - - /** - * TCP/IP Checksum operation. - * - * @author GCHQ Contributor [1] - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - * - * @example - * // returns '3f2c' - * Checksum.runTcpIp([0x45,0x00,0x00,0x87,0xa3,0x1b,0x40,0x00,0x40,0x06, - * 0x00,0x00,0xac,0x11,0x00,0x04,0xac,0x11,0x00,0x03]) - * - * // returns 'a249' - * Checksum.runTcpIp([0x45,0x00,0x01,0x11,0x3f,0x74,0x40,0x00,0x40,0x06, - * 0x00,0x00,0xac,0x11,0x00,0x03,0xac,0x11,0x00,0x04]) - */ - runTCPIP: function(input, args) { - let csum = 0; - - for (let i = 0; i < input.length; i++) { - if (i % 2 === 0) { - csum += (input[i] << 8); - } else { - csum += input[i]; - } - } - - csum = (csum >> 16) + (csum & 0xffff); - - return Utils.hex(0xffff - csum); - }, - -}; - -export default Checksum; diff --git a/src/core/operations/legacy/Compress.js b/src/core/operations/legacy/Compress.js deleted file mode 100755 index 2313541d..00000000 --- a/src/core/operations/legacy/Compress.js +++ /dev/null @@ -1,243 +0,0 @@ -import Utils from "../Utils.js"; -import bzip2 from "exports-loader?bzip2!../vendor/bzip2.js"; - - -/** - * Compression operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Compress = { - - /** - * Bzip2 Decompress operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runBzip2Decompress: function(input, args) { - let compressed = new Uint8Array(input), - bzip2Reader, - plain = ""; - - bzip2Reader = bzip2.array(compressed); - plain = bzip2.simple(bzip2Reader); - return plain; - }, - - - /** - * @constant - * @default - */ - TAR_FILENAME: "file.txt", - - - /** - * Tar pack operation. - * - * @author tlwr [toby@toby.codes] - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {byteArray} - */ - runTar: function(input, args) { - const Tarball = function() { - this.bytes = new Array(512); - this.position = 0; - }; - - Tarball.prototype.addEmptyBlock = function() { - const filler = new Array(512); - filler.fill(0); - this.bytes = this.bytes.concat(filler); - }; - - Tarball.prototype.writeBytes = function(bytes) { - const self = this; - - if (this.position + bytes.length > this.bytes.length) { - this.addEmptyBlock(); - } - - Array.prototype.forEach.call(bytes, function(b, i) { - if (typeof b.charCodeAt !== "undefined") { - b = b.charCodeAt(); - } - - self.bytes[self.position] = b; - self.position += 1; - }); - }; - - Tarball.prototype.writeEndBlocks = function() { - const numEmptyBlocks = 2; - for (let i = 0; i < numEmptyBlocks; i++) { - this.addEmptyBlock(); - } - }; - - const fileSize = input.length.toString(8).padStart(11, "0"); - const currentUnixTimestamp = Math.floor(Date.now() / 1000); - const lastModTime = currentUnixTimestamp.toString(8).padStart(11, "0"); - - const file = { - fileName: Utils.padBytesRight(args[0], 100), - fileMode: Utils.padBytesRight("0000664", 8), - ownerUID: Utils.padBytesRight("0", 8), - ownerGID: Utils.padBytesRight("0", 8), - size: Utils.padBytesRight(fileSize, 12), - lastModTime: Utils.padBytesRight(lastModTime, 12), - checksum: " ", - type: "0", - linkedFileName: Utils.padBytesRight("", 100), - USTARFormat: Utils.padBytesRight("ustar", 6), - version: "00", - ownerUserName: Utils.padBytesRight("", 32), - ownerGroupName: Utils.padBytesRight("", 32), - deviceMajor: Utils.padBytesRight("", 8), - deviceMinor: Utils.padBytesRight("", 8), - fileNamePrefix: Utils.padBytesRight("", 155), - }; - - let checksum = 0; - for (const key in file) { - const bytes = file[key]; - Array.prototype.forEach.call(bytes, function(b) { - if (typeof b.charCodeAt !== "undefined") { - checksum += b.charCodeAt(); - } else { - checksum += b; - } - }); - } - checksum = Utils.padBytesRight(checksum.toString(8).padStart(7, "0"), 8); - file.checksum = checksum; - - const tarball = new Tarball(); - tarball.writeBytes(file.fileName); - tarball.writeBytes(file.fileMode); - tarball.writeBytes(file.ownerUID); - tarball.writeBytes(file.ownerGID); - tarball.writeBytes(file.size); - tarball.writeBytes(file.lastModTime); - tarball.writeBytes(file.checksum); - tarball.writeBytes(file.type); - tarball.writeBytes(file.linkedFileName); - tarball.writeBytes(file.USTARFormat); - tarball.writeBytes(file.version); - tarball.writeBytes(file.ownerUserName); - tarball.writeBytes(file.ownerGroupName); - tarball.writeBytes(file.deviceMajor); - tarball.writeBytes(file.deviceMinor); - tarball.writeBytes(file.fileNamePrefix); - tarball.writeBytes(Utils.padBytesRight("", 12)); - tarball.writeBytes(input); - tarball.writeEndBlocks(); - - return tarball.bytes; - }, - - - /** - * Untar unpack operation. - * - * @author tlwr [toby@toby.codes] - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {html} - */ - runUntar: function(input, args) { - const Stream = function(input) { - this.bytes = input; - this.position = 0; - }; - - Stream.prototype.getBytes = function(bytesToGet) { - const newPosition = this.position + bytesToGet; - const bytes = this.bytes.slice(this.position, newPosition); - this.position = newPosition; - return bytes; - }; - - Stream.prototype.readString = function(numBytes) { - let result = ""; - for (let i = this.position; i < this.position + numBytes; i++) { - const currentByte = this.bytes[i]; - if (currentByte === 0) break; - result += String.fromCharCode(currentByte); - } - this.position += numBytes; - return result; - }; - - Stream.prototype.readInt = function(numBytes, base) { - const string = this.readString(numBytes); - return parseInt(string, base); - }; - - Stream.prototype.hasMore = function() { - return this.position < this.bytes.length; - }; - - let stream = new Stream(input), - files = []; - - while (stream.hasMore()) { - const dataPosition = stream.position + 512; - - const file = { - fileName: stream.readString(100), - fileMode: stream.readString(8), - ownerUID: stream.readString(8), - ownerGID: stream.readString(8), - size: parseInt(stream.readString(12), 8), // Octal - lastModTime: new Date(1000 * stream.readInt(12, 8)), // Octal - checksum: stream.readString(8), - type: stream.readString(1), - linkedFileName: stream.readString(100), - USTARFormat: stream.readString(6).indexOf("ustar") >= 0, - }; - - if (file.USTARFormat) { - file.version = stream.readString(2); - file.ownerUserName = stream.readString(32); - file.ownerGroupName = stream.readString(32); - file.deviceMajor = stream.readString(8); - file.deviceMinor = stream.readString(8); - file.filenamePrefix = stream.readString(155); - } - - stream.position = dataPosition; - - if (file.type === "0") { - // File - files.push(file); - let endPosition = stream.position + file.size; - if (file.size % 512 !== 0) { - endPosition += 512 - (file.size % 512); - } - - file.bytes = stream.getBytes(file.size); - file.contents = Utils.byteArrayToUtf8(file.bytes); - stream.position = endPosition; - } else if (file.type === "5") { - // Directory - files.push(file); - } else { - // Symlink or empty bytes - } - } - - return Utils.displayFilesAsHTML(files); - }, -}; - -export default Compress; diff --git a/src/core/operations/legacy/Convert.js b/src/core/operations/legacy/Convert.js deleted file mode 100755 index a79a5c3f..00000000 --- a/src/core/operations/legacy/Convert.js +++ /dev/null @@ -1,413 +0,0 @@ -/** - * Unit conversion operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Convert = { - - /** - * @constant - * @default - */ - DISTANCE_UNITS: [ - "[Metric]", "Nanometres (nm)", "Micrometres (µm)", "Millimetres (mm)", "Centimetres (cm)", "Metres (m)", "Kilometers (km)", "[/Metric]", - "[Imperial]", "Thou (th)", "Inches (in)", "Feet (ft)", "Yards (yd)", "Chains (ch)", "Furlongs (fur)", "Miles (mi)", "Leagues (lea)", "[/Imperial]", - "[Maritime]", "Fathoms (ftm)", "Cables", "Nautical miles", "[/Maritime]", - "[Comparisons]", "Cars (4m)", "Buses (8.4m)", "American football fields (91m)", "Football pitches (105m)", "[/Comparisons]", - "[Astronomical]", "Earth-to-Moons", "Earth's equators", "Astronomical units (au)", "Light-years (ly)", "Parsecs (pc)", "[/Astronomical]", - ], - /** - * @constant - * @default - */ - DISTANCE_FACTOR: { // Multiples of a metre - "Nanometres (nm)": 1e-9, - "Micrometres (µm)": 1e-6, - "Millimetres (mm)": 1e-3, - "Centimetres (cm)": 1e-2, - "Metres (m)": 1, - "Kilometers (km)": 1e3, - - "Thou (th)": 0.0000254, - "Inches (in)": 0.0254, - "Feet (ft)": 0.3048, - "Yards (yd)": 0.9144, - "Chains (ch)": 20.1168, - "Furlongs (fur)": 201.168, - "Miles (mi)": 1609.344, - "Leagues (lea)": 4828.032, - - "Fathoms (ftm)": 1.853184, - "Cables": 185.3184, - "Nautical miles": 1853.184, - - "Cars (4m)": 4, - "Buses (8.4m)": 8.4, - "American football fields (91m)": 91, - "Football pitches (105m)": 105, - - "Earth-to-Moons": 380000000, - "Earth's equators": 40075016.686, - "Astronomical units (au)": 149597870700, - "Light-years (ly)": 9460730472580800, - "Parsecs (pc)": 3.0856776e16 - }, - - /** - * Convert distance operation. - * - * @param {BigNumber} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runDistance: function (input, args) { - let inputUnits = args[0], - outputUnits = args[1]; - - input = input.times(Convert.DISTANCE_FACTOR[inputUnits]); - return input.div(Convert.DISTANCE_FACTOR[outputUnits]); - }, - - - /** - * @constant - * @default - */ - DATA_UNITS: [ - "Bits (b)", "Nibbles", "Octets", "Bytes (B)", - "[Binary bits (2^n)]", "Kibibits (Kib)", "Mebibits (Mib)", "Gibibits (Gib)", "Tebibits (Tib)", "Pebibits (Pib)", "Exbibits (Eib)", "Zebibits (Zib)", "Yobibits (Yib)", "[/Binary bits (2^n)]", - "[Decimal bits (10^n)]", "Decabits", "Hectobits", "Kilobits (kb)", "Megabits (Mb)", "Gigabits (Gb)", "Terabits (Tb)", "Petabits (Pb)", "Exabits (Eb)", "Zettabits (Zb)", "Yottabits (Yb)", "[/Decimal bits (10^n)]", - "[Binary bytes (8 x 2^n)]", "Kibibytes (KiB)", "Mebibytes (MiB)", "Gibibytes (GiB)", "Tebibytes (TiB)", "Pebibytes (PiB)", "Exbibytes (EiB)", "Zebibytes (ZiB)", "Yobibytes (YiB)", "[/Binary bytes (8 x 2^n)]", - "[Decimal bytes (8 x 10^n)]", "Kilobytes (KB)", "Megabytes (MB)", "Gigabytes (GB)", "Terabytes (TB)", "Petabytes (PB)", "Exabytes (EB)", "Zettabytes (ZB)", "Yottabytes (YB)", "[/Decimal bytes (8 x 10^n)]" - ], - /** - * @constant - * @default - */ - DATA_FACTOR: { // Multiples of a bit - "Bits (b)": 1, - "Nibbles": 4, - "Octets": 8, - "Bytes (B)": 8, - - // Binary bits (2^n) - "Kibibits (Kib)": 1024, - "Mebibits (Mib)": 1048576, - "Gibibits (Gib)": 1073741824, - "Tebibits (Tib)": 1099511627776, - "Pebibits (Pib)": 1125899906842624, - "Exbibits (Eib)": 1152921504606846976, - "Zebibits (Zib)": 1180591620717411303424, - "Yobibits (Yib)": 1208925819614629174706176, - - // Decimal bits (10^n) - "Decabits": 10, - "Hectobits": 100, - "Kilobits (Kb)": 1e3, - "Megabits (Mb)": 1e6, - "Gigabits (Gb)": 1e9, - "Terabits (Tb)": 1e12, - "Petabits (Pb)": 1e15, - "Exabits (Eb)": 1e18, - "Zettabits (Zb)": 1e21, - "Yottabits (Yb)": 1e24, - - // Binary bytes (8 x 2^n) - "Kibibytes (KiB)": 8192, - "Mebibytes (MiB)": 8388608, - "Gibibytes (GiB)": 8589934592, - "Tebibytes (TiB)": 8796093022208, - "Pebibytes (PiB)": 9007199254740992, - "Exbibytes (EiB)": 9223372036854775808, - "Zebibytes (ZiB)": 9444732965739290427392, - "Yobibytes (YiB)": 9671406556917033397649408, - - // Decimal bytes (8 x 10^n) - "Kilobytes (KB)": 8e3, - "Megabytes (MB)": 8e6, - "Gigabytes (GB)": 8e9, - "Terabytes (TB)": 8e12, - "Petabytes (PB)": 8e15, - "Exabytes (EB)": 8e18, - "Zettabytes (ZB)": 8e21, - "Yottabytes (YB)": 8e24, - }, - - /** - * Convert data units operation. - * - * @param {BigNumber} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runDataSize: function (input, args) { - let inputUnits = args[0], - outputUnits = args[1]; - - input = input.times(Convert.DATA_FACTOR[inputUnits]); - return input.div(Convert.DATA_FACTOR[outputUnits]); - }, - - - /** - * @constant - * @default - */ - AREA_UNITS: [ - "[Metric]", "Square metre (sq m)", "Square kilometre (sq km)", "Centiare (ca)", "Deciare (da)", "Are (a)", "Decare (daa)", "Hectare (ha)", "[/Metric]", - "[Imperial]", "Square inch (sq in)", "Square foot (sq ft)", "Square yard (sq yd)", "Square mile (sq mi)", "Perch (sq per)", "Rood (ro)", "International acre (ac)", "[/Imperial]", - "[US customary units]", "US survey acre (ac)", "US survey square mile (sq mi)", "US survey township", "[/US customary units]", - "[Nuclear physics]", "Yoctobarn (yb)", "Zeptobarn (zb)", "Attobarn (ab)", "Femtobarn (fb)", "Picobarn (pb)", "Nanobarn (nb)", "Microbarn (μb)", "Millibarn (mb)", "Barn (b)", "Kilobarn (kb)", "Megabarn (Mb)", "Outhouse", "Shed", "Planck area", "[/Nuclear physics]", - "[Comparisons]", "Washington D.C.", "Isle of Wight", "Wales", "Texas", "[/Comparisons]", - ], - /** - * @constant - * @default - */ - AREA_FACTOR: { // Multiples of a square metre - // Metric - "Square metre (sq m)": 1, - "Square kilometre (sq km)": 1e6, - - "Centiare (ca)": 1, - "Deciare (da)": 10, - "Are (a)": 100, - "Decare (daa)": 1e3, - "Hectare (ha)": 1e4, - - // Imperial - "Square inch (sq in)": 0.00064516, - "Square foot (sq ft)": 0.09290304, - "Square yard (sq yd)": 0.83612736, - "Square mile (sq mi)": 2589988.110336, - "Perch (sq per)": 42.21, - "Rood (ro)": 1011, - "International acre (ac)": 4046.8564224, - - // US customary units - "US survey acre (ac)": 4046.87261, - "US survey square mile (sq mi)": 2589998.470305239, - "US survey township": 93239944.9309886, - - // Nuclear physics - "Yoctobarn (yb)": 1e-52, - "Zeptobarn (zb)": 1e-49, - "Attobarn (ab)": 1e-46, - "Femtobarn (fb)": 1e-43, - "Picobarn (pb)": 1e-40, - "Nanobarn (nb)": 1e-37, - "Microbarn (μb)": 1e-34, - "Millibarn (mb)": 1e-31, - "Barn (b)": 1e-28, - "Kilobarn (kb)": 1e-25, - "Megabarn (Mb)": 1e-22, - - "Planck area": 2.6e-70, - "Shed": 1e-52, - "Outhouse": 1e-34, - - // Comparisons - "Washington D.C.": 176119191.502848, - "Isle of Wight": 380000000, - "Wales": 20779000000, - "Texas": 696241000000, - }, - - /** - * Convert area operation. - * - * @param {BigNumber} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runArea: function (input, args) { - let inputUnits = args[0], - outputUnits = args[1]; - - input = input.times(Convert.AREA_FACTOR[inputUnits]); - return input.div(Convert.AREA_FACTOR[outputUnits]); - }, - - - /** - * @constant - * @default - */ - MASS_UNITS: [ - "[Metric]", "Yoctogram (yg)", "Zeptogram (zg)", "Attogram (ag)", "Femtogram (fg)", "Picogram (pg)", "Nanogram (ng)", "Microgram (μg)", "Milligram (mg)", "Centigram (cg)", "Decigram (dg)", "Gram (g)", "Decagram (dag)", "Hectogram (hg)", "Kilogram (kg)", "Megagram (Mg)", "Tonne (t)", "Gigagram (Gg)", "Teragram (Tg)", "Petagram (Pg)", "Exagram (Eg)", "Zettagram (Zg)", "Yottagram (Yg)", "[/Metric]", - "[Imperial Avoirdupois]", "Grain (gr)", "Dram (dr)", "Ounce (oz)", "Pound (lb)", "Nail", "Stone (st)", "Quarter (gr)", "Tod", "US hundredweight (cwt)", "Imperial hundredweight (cwt)", "US ton (t)", "Imperial ton (t)", "[/Imperial Avoirdupois]", - "[Imperial Troy]", "Grain (gr)", "Pennyweight (dwt)", "Troy dram (dr t)", "Troy ounce (oz t)", "Troy pound (lb t)", "Mark", "[/Imperial Troy]", - "[Archaic]", "Wey", "Wool wey", "Suffolk wey", "Wool sack", "Coal sack", "Load", "Last", "Flax or feather last", "Gunpowder last", "Picul", "Rice last", "[/Archaic]", - "[Comparisons]", "Big Ben (14 tonnes)", "Blue whale (180 tonnes)", "International Space Station (417 tonnes)", "Space Shuttle (2,041 tonnes)", "RMS Titanic (52,000 tonnes)", "Great Pyramid of Giza (6,000,000 tonnes)", "Earth's oceans (1.4 yottagrams)", "[/Comparisons]", - "[Astronomical]", "A teaspoon of neutron star (5,500 million tonnes)", "Lunar mass (ML)", "Earth mass (M⊕)", "Jupiter mass (MJ)", "Solar mass (M☉)", "Sagittarius A* (7.5 x 10^36 kgs-ish)", "Milky Way galaxy (1.2 x 10^42 kgs)", "The observable universe (1.45 x 10^53 kgs)", "[/Astronomical]", - ], - /** - * @constant - * @default - */ - MASS_FACTOR: { // Multiples of a gram - // Metric - "Yoctogram (yg)": 1e-24, - "Zeptogram (zg)": 1e-21, - "Attogram (ag)": 1e-18, - "Femtogram (fg)": 1e-15, - "Picogram (pg)": 1e-12, - "Nanogram (ng)": 1e-9, - "Microgram (μg)": 1e-6, - "Milligram (mg)": 1e-3, - "Centigram (cg)": 1e-2, - "Decigram (dg)": 1e-1, - "Gram (g)": 1, - "Decagram (dag)": 10, - "Hectogram (hg)": 100, - "Kilogram (kg)": 1000, - "Megagram (Mg)": 1e6, - "Tonne (t)": 1e6, - "Gigagram (Gg)": 1e9, - "Teragram (Tg)": 1e12, - "Petagram (Pg)": 1e15, - "Exagram (Eg)": 1e18, - "Zettagram (Zg)": 1e21, - "Yottagram (Yg)": 1e24, - - // Imperial Avoirdupois - "Grain (gr)": 64.79891e-3, - "Dram (dr)": 1.7718451953125, - "Ounce (oz)": 28.349523125, - "Pound (lb)": 453.59237, - "Nail": 3175.14659, - "Stone (st)": 6.35029318e3, - "Quarter (gr)": 12700.58636, - "Tod": 12700.58636, - "US hundredweight (cwt)": 45.359237e3, - "Imperial hundredweight (cwt)": 50.80234544e3, - "US ton (t)": 907.18474e3, - "Imperial ton (t)": 1016.0469088e3, - - // Imperial Troy - "Pennyweight (dwt)": 1.55517384, - "Troy dram (dr t)": 3.8879346, - "Troy ounce (oz t)": 31.1034768, - "Troy pound (lb t)": 373.2417216, - "Mark": 248.8278144, - - // Archaic - "Wey": 76.5e3, - "Wool wey": 101.7e3, - "Suffolk wey": 161.5e3, - "Wool sack": 153000, - "Coal sack": 50.80234544e3, - "Load": 918000, - "Last": 1836000, - "Flax or feather last": 770e3, - "Gunpowder last": 1090e3, - "Picul": 60.478982e3, - "Rice last": 1200e3, - - // Comparisons - "Big Ben (14 tonnes)": 14e6, - "Blue whale (180 tonnes)": 180e6, - "International Space Station (417 tonnes)": 417e6, - "Space Shuttle (2,041 tonnes)": 2041e6, - "RMS Titanic (52,000 tonnes)": 52000e6, - "Great Pyramid of Giza (6,000,000 tonnes)": 6e12, - "Earth's oceans (1.4 yottagrams)": 1.4e24, - - // Astronomical - "A teaspoon of neutron star (5,500 million tonnes)": 5.5e15, - "Lunar mass (ML)": 7.342e25, - "Earth mass (M⊕)": 5.97219e27, - "Jupiter mass (MJ)": 1.8981411476999997e30, - "Solar mass (M☉)": 1.98855e33, - "Sagittarius A* (7.5 x 10^36 kgs-ish)": 7.5e39, - "Milky Way galaxy (1.2 x 10^42 kgs)": 1.2e45, - "The observable universe (1.45 x 10^53 kgs)": 1.45e56, - }, - - /** - * Convert mass operation. - * - * @param {BigNumber} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runMass: function (input, args) { - let inputUnits = args[0], - outputUnits = args[1]; - - input = input.times(Convert.MASS_FACTOR[inputUnits]); - return input.div(Convert.MASS_FACTOR[outputUnits]); - }, - - - /** - * @constant - * @default - */ - SPEED_UNITS: [ - "[Metric]", "Metres per second (m/s)", "Kilometres per hour (km/h)", "[/Metric]", - "[Imperial]", "Miles per hour (mph)", "Knots (kn)", "[/Imperial]", - "[Comparisons]", "Human hair growth rate", "Bamboo growth rate", "World's fastest snail", "Usain Bolt's top speed", "Jet airliner cruising speed", "Concorde", "SR-71 Blackbird", "Space Shuttle", "International Space Station", "[/Comparisons]", - "[Scientific]", "Sound in standard atmosphere", "Sound in water", "Lunar escape velocity", "Earth escape velocity", "Earth's solar orbit", "Solar system's Milky Way orbit", "Milky Way relative to the cosmic microwave background", "Solar escape velocity", "Neutron star escape velocity (0.3c)", "Light in a diamond (0.4136c)", "Signal in an optical fibre (0.667c)", "Light (c)", "[/Scientific]", - ], - /** - * @constant - * @default - */ - SPEED_FACTOR: { // Multiples of m/s - // Metric - "Metres per second (m/s)": 1, - "Kilometres per hour (km/h)": 0.2778, - - // Imperial - "Miles per hour (mph)": 0.44704, - "Knots (kn)": 0.5144, - - // Comparisons - "Human hair growth rate": 4.8e-9, - "Bamboo growth rate": 1.4e-5, - "World's fastest snail": 0.00275, - "Usain Bolt's top speed": 12.42, - "Jet airliner cruising speed": 250, - "Concorde": 603, - "SR-71 Blackbird": 981, - "Space Shuttle": 1400, - "International Space Station": 7700, - - // Scientific - "Sound in standard atmosphere": 340.3, - "Sound in water": 1500, - "Lunar escape velocity": 2375, - "Earth escape velocity": 11200, - "Earth's solar orbit": 29800, - "Solar system's Milky Way orbit": 200000, - "Milky Way relative to the cosmic microwave background": 552000, - "Solar escape velocity": 617700, - "Neutron star escape velocity (0.3c)": 100000000, - "Light in a diamond (0.4136c)": 124000000, - "Signal in an optical fibre (0.667c)": 200000000, - "Light (c)": 299792458, - }, - - /** - * Convert speed operation. - * - * @param {BigNumber} input - * @param {Object[]} args - * @returns {BigNumber} - */ - runSpeed: function (input, args) { - let inputUnits = args[0], - outputUnits = args[1]; - - input = input.times(Convert.SPEED_FACTOR[inputUnits]); - return input.div(Convert.SPEED_FACTOR[outputUnits]); - }, - -}; - -export default Convert; diff --git a/src/core/operations/legacy/DateTime.js b/src/core/operations/legacy/DateTime.js deleted file mode 100755 index b117a2ca..00000000 --- a/src/core/operations/legacy/DateTime.js +++ /dev/null @@ -1,484 +0,0 @@ -import moment from "moment-timezone"; - - -/** - * Date and time operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const DateTime = { - - /** - * @constant - * @default - */ - UNITS: ["Seconds (s)", "Milliseconds (ms)", "Microseconds (μs)", "Nanoseconds (ns)"], - - /** - * From UNIX Timestamp operation. - * - * @param {number} input - * @param {Object[]} args - * @returns {string} - */ - runFromUnixTimestamp: function(input, args) { - let units = args[0], - d; - - input = parseFloat(input); - - if (units === "Seconds (s)") { - d = moment.unix(input); - return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss") + " UTC"; - } else if (units === "Milliseconds (ms)") { - d = moment(input); - return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss.SSS") + " UTC"; - } else if (units === "Microseconds (μs)") { - d = moment(input / 1000); - return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss.SSS") + " UTC"; - } else if (units === "Nanoseconds (ns)") { - d = moment(input / 1000000); - return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss.SSS") + " UTC"; - } else { - throw "Unrecognised unit"; - } - }, - - - /** - * @constant - * @default - */ - TREAT_AS_UTC: true, - - /** - * To UNIX Timestamp operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runToUnixTimestamp: function(input, args) { - const units = args[0], - treatAsUTC = args[1], - showDateTime = args[2], - d = treatAsUTC ? moment.utc(input) : moment(input); - - let result = ""; - - if (units === "Seconds (s)") { - result = d.unix(); - } else if (units === "Milliseconds (ms)") { - result = d.valueOf(); - } else if (units === "Microseconds (μs)") { - result = d.valueOf() * 1000; - } else if (units === "Nanoseconds (ns)") { - result = d.valueOf() * 1000000; - } else { - throw "Unrecognised unit"; - } - - return showDateTime ? `${result} (${d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss")} UTC)` : result.toString(); - }, - - - /** - * @constant - * @default - */ - DATETIME_FORMATS: [ - { - name: "Standard date and time", - value: "DD/MM/YYYY HH:mm:ss" - }, - { - name: "American-style date and time", - value: "MM/DD/YYYY HH:mm:ss" - }, - { - name: "International date and time", - value: "YYYY-MM-DD HH:mm:ss" - }, - { - name: "Verbose date and time", - value: "dddd Do MMMM YYYY HH:mm:ss Z z" - }, - { - name: "UNIX timestamp (seconds)", - value: "X" - }, - { - name: "UNIX timestamp offset (milliseconds)", - value: "x" - }, - { - name: "Automatic", - value: "" - }, - ], - /** - * @constant - * @default - */ - INPUT_FORMAT_STRING: "DD/MM/YYYY HH:mm:ss", - /** - * @constant - * @default - */ - OUTPUT_FORMAT_STRING: "dddd Do MMMM YYYY HH:mm:ss Z z", - /** - * @constant - * @default - */ - TIMEZONES: ["UTC"].concat(moment.tz.names()), - - /** - * Translate DateTime Format operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {html} - */ - runTranslateFormat: function(input, args) { - let inputFormat = args[1], - inputTimezone = args[2], - outputFormat = args[3], - outputTimezone = args[4], - date; - - try { - date = moment.tz(input, inputFormat, inputTimezone); - if (!date || date.format() === "Invalid date") throw Error; - } catch (err) { - return "Invalid format.\n\n" + DateTime.FORMAT_EXAMPLES; - } - - return date.tz(outputTimezone).format(outputFormat); - }, - - - /** - * Parse DateTime operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {html} - */ - runParse: function(input, args) { - let inputFormat = args[1], - inputTimezone = args[2], - date, - output = ""; - - try { - date = moment.tz(input, inputFormat, inputTimezone); - if (!date || date.format() === "Invalid date") throw Error; - } catch (err) { - return "Invalid format.\n\n" + DateTime.FORMAT_EXAMPLES; - } - - output += "Date: " + date.format("dddd Do MMMM YYYY") + - "\nTime: " + date.format("HH:mm:ss") + - "\nPeriod: " + date.format("A") + - "\nTimezone: " + date.format("z") + - "\nUTC offset: " + date.format("ZZ") + - "\n\nDaylight Saving Time: " + date.isDST() + - "\nLeap year: " + date.isLeapYear() + - "\nDays in this month: " + date.daysInMonth() + - "\n\nDay of year: " + date.dayOfYear() + - "\nWeek number: " + date.weekYear() + - "\nQuarter: " + date.quarter(); - - return output; - }, - - - /** - * Sleep operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {ArrayBuffer} - */ - runSleep: async function(input, args) { - const ms = args[0]; - await new Promise(r => setTimeout(r, ms)); - return input; - }, - - - /** - * @constant - */ - FORMAT_EXAMPLES: `Format string tokens: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CategoryTokenOutput
MonthM1 2 ... 11 12
Mo1st 2nd ... 11th 12th
MM01 02 ... 11 12
MMMJan Feb ... Nov Dec
MMMMJanuary February ... November December
QuarterQ1 2 3 4
Day of MonthD1 2 ... 30 31
Do1st 2nd ... 30th 31st
DD01 02 ... 30 31
Day of YearDDD1 2 ... 364 365
DDDo1st 2nd ... 364th 365th
DDDD001 002 ... 364 365
Day of Weekd0 1 ... 5 6
do0th 1st ... 5th 6th
ddSu Mo ... Fr Sa
dddSun Mon ... Fri Sat
ddddSunday Monday ... Friday Saturday
Day of Week (Locale)e0 1 ... 5 6
Day of Week (ISO)E1 2 ... 6 7
Week of Yearw1 2 ... 52 53
wo1st 2nd ... 52nd 53rd
ww01 02 ... 52 53
Week of Year (ISO)W1 2 ... 52 53
Wo1st 2nd ... 52nd 53rd
WW01 02 ... 52 53
YearYY70 71 ... 29 30
YYYY1970 1971 ... 2029 2030
Week Yeargg70 71 ... 29 30
gggg1970 1971 ... 2029 2030
Week Year (ISO)GG70 71 ... 29 30
GGGG1970 1971 ... 2029 2030
AM/PMAAM PM
aam pm
HourH0 1 ... 22 23
HH00 01 ... 22 23
h1 2 ... 11 12
hh01 02 ... 11 12
Minutem0 1 ... 58 59
mm00 01 ... 58 59
Seconds0 1 ... 58 59
ss00 01 ... 58 59
Fractional SecondS0 1 ... 8 9
SS00 01 ... 98 99
SSS000 001 ... 998 999
SSSS ... SSSSSSSSS000[0..] 001[0..] ... 998[0..] 999[0..]
Timezonez or zzEST CST ... MST PST
Z-07:00 -06:00 ... +06:00 +07:00
ZZ-0700 -0600 ... +0600 +0700
Unix TimestampX1360013296
Unix Millisecond Timestampx1360013296123
`, - -}; - -export default DateTime; diff --git a/src/core/operations/legacy/Diff.js b/src/core/operations/legacy/Diff.js deleted file mode 100644 index afa00c37..00000000 --- a/src/core/operations/legacy/Diff.js +++ /dev/null @@ -1,94 +0,0 @@ -import Utils from "../Utils.js"; -import * as JsDiff from "diff"; - - -/** - * Diff operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Diff = { - - /** - * @constant - * @default - */ - DIFF_SAMPLE_DELIMITER: "\\n\\n", - /** - * @constant - * @default - */ - DIFF_BY: ["Character", "Word", "Line", "Sentence", "CSS", "JSON"], - - /** - * Diff operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {html} - */ - runDiff: function(input, args) { - let sampleDelim = args[0], - diffBy = args[1], - showAdded = args[2], - showRemoved = args[3], - ignoreWhitespace = args[4], - samples = input.split(sampleDelim), - output = "", - diff; - - if (!samples || samples.length !== 2) { - return "Incorrect number of samples, perhaps you need to modify the sample delimiter or add more samples?"; - } - - switch (diffBy) { - case "Character": - diff = JsDiff.diffChars(samples[0], samples[1]); - break; - case "Word": - if (ignoreWhitespace) { - diff = JsDiff.diffWords(samples[0], samples[1]); - } else { - diff = JsDiff.diffWordsWithSpace(samples[0], samples[1]); - } - break; - case "Line": - if (ignoreWhitespace) { - diff = JsDiff.diffTrimmedLines(samples[0], samples[1]); - } else { - diff = JsDiff.diffLines(samples[0], samples[1]); - } - break; - case "Sentence": - diff = JsDiff.diffSentences(samples[0], samples[1]); - break; - case "CSS": - diff = JsDiff.diffCss(samples[0], samples[1]); - break; - case "JSON": - diff = JsDiff.diffJson(samples[0], samples[1]); - break; - default: - return "Invalid 'Diff by' option."; - } - - for (let i = 0; i < diff.length; i++) { - if (diff[i].added) { - if (showAdded) output += "" + Utils.escapeHtml(diff[i].value) + ""; - } else if (diff[i].removed) { - if (showRemoved) output += "" + Utils.escapeHtml(diff[i].value) + ""; - } else { - output += Utils.escapeHtml(diff[i].value); - } - } - - return output; - }, - -}; - -export default Diff; diff --git a/src/core/operations/legacy/Endian.js b/src/core/operations/legacy/Endian.js deleted file mode 100755 index a2ec7703..00000000 --- a/src/core/operations/legacy/Endian.js +++ /dev/null @@ -1,100 +0,0 @@ -import Utils from "../Utils.js"; -import {toHex, fromHex} from "../lib/Hex"; - - -/** - * Endian operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Endian = { - - /** - * @constant - * @default - */ - DATA_FORMAT: ["Hex", "Raw"], - /** - * @constant - * @default - */ - WORD_LENGTH: 4, - /** - * @constant - * @default - */ - PAD_INCOMPLETE_WORDS: true, - - /** - * Swap endianness operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runSwapEndianness: function(input, args) { - let dataFormat = args[0], - wordLength = args[1], - padIncompleteWords = args[2], - data = [], - result = [], - words = [], - i = 0, - j = 0; - - if (wordLength <= 0) { - return "Word length must be greater than 0"; - } - - // Convert input to raw data based on specified data format - switch (dataFormat) { - case "Hex": - data = fromHex(input); - break; - case "Raw": - data = Utils.strToByteArray(input); - break; - default: - data = input; - } - - // Split up into words - for (i = 0; i < data.length; i += wordLength) { - const word = data.slice(i, i + wordLength); - - // Pad word if too short - if (padIncompleteWords && word.length < wordLength){ - for (j = word.length; j < wordLength; j++) { - word.push(0); - } - } - - words.push(word); - } - - // Swap endianness and flatten - for (i = 0; i < words.length; i++) { - j = words[i].length; - while (j--) { - result.push(words[i][j]); - } - } - - // Convert data back to specified data format - switch (dataFormat) { - case "Hex": - return toHex(result); - case "Raw": - return Utils.byteArrayToUtf8(result); - default: - return result; - } - }, - -}; - -export default Endian; diff --git a/src/core/operations/legacy/Entropy.js b/src/core/operations/legacy/Entropy.js deleted file mode 100755 index baf9edb3..00000000 --- a/src/core/operations/legacy/Entropy.js +++ /dev/null @@ -1,195 +0,0 @@ -import Utils from "../Utils.js"; - - -/** - * Entropy operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Entropy = { - - /** - * @constant - * @default - */ - CHUNK_SIZE: 1000, - - /** - * Entropy operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {html} - */ - runEntropy: function(input, args) { - let chunkSize = args[0], - output = "", - entropy = Entropy._calcEntropy(input); - - output += "Shannon entropy: " + entropy + "\n" + - "

\n" + - "- 0 represents no randomness (i.e. all the bytes in the data have the same value) whereas 8, the maximum, represents a completely random string.\n" + - "- Standard English text usually falls somewhere between 3.5 and 5.\n" + - "- Properly encrypted or compressed data of a reasonable length should have an entropy of over 7.5.\n\n" + - "The following results show the entropy of chunks of the input data. Chunks with particularly high entropy could suggest encrypted or compressed sections.\n\n" + - "
"; - - let chunkEntropy = 0; - if (chunkSize !== 0) { - for (let i = 0; i < input.length; i += chunkSize) { - chunkEntropy = Entropy._calcEntropy(input.slice(i, i+chunkSize)); - output += "Bytes " + i + " to " + (i+chunkSize) + ": " + chunkEntropy + "\n"; - } - } else { - output += "Chunk size cannot be 0."; - } - - return output; - }, - - - /** - * @constant - * @default - */ - FREQ_ZEROS: false, - - /** - * Frequency distribution operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {html} - */ - runFreqDistrib: function (input, args) { - const data = new Uint8Array(input); - if (!data.length) return "No data"; - - let distrib = new Array(256).fill(0), - percentages = new Array(256), - len = data.length, - showZeroes = args[0], - i; - - // Count bytes - for (i = 0; i < len; i++) { - distrib[data[i]]++; - } - - // Calculate percentages - let repr = 0; - for (i = 0; i < 256; i++) { - if (distrib[i] > 0) repr++; - percentages[i] = distrib[i] / len * 100; - } - - // Print - let output = "
" + - "Total data length: " + len + - "\nNumber of bytes represented: " + repr + - "\nNumber of bytes not represented: " + (256-repr) + - "\n\nByte Percentage\n" + - ""; - - for (i = 0; i < 256; i++) { - if (distrib[i] || showZeroes) { - output += " " + Utils.hex(i, 2) + " (" + - (percentages[i].toFixed(2).replace(".00", "") + "%)").padEnd(8, " ") + - Array(Math.ceil(percentages[i])+1).join("|") + "\n"; - } - } - - return output; - }, - - - /** - * Chi Square operation. - * - * @param {ArrayBuffer} data - * @param {Object[]} args - * @returns {number} - */ - runChiSq: function(input, args) { - const data = new Uint8Array(input); - let distArray = new Array(256).fill(0), - total = 0; - - for (let i = 0; i < data.length; i++) { - distArray[data[i]]++; - } - - for (let i = 0; i < distArray.length; i++) { - if (distArray[i] > 0) { - total += Math.pow(distArray[i] - data.length / 256, 2) / (data.length / 256); - } - } - - return total; - }, - - - /** - * Calculates the Shannon entropy for a given chunk of data. - * - * @private - * @param {byteArray} data - * @returns {number} - */ - _calcEntropy: function(data) { - let prob = [], - uniques = data.unique(), - str = Utils.byteArrayToChars(data), - i; - - for (i = 0; i < uniques.length; i++) { - prob.push(str.count(Utils.chr(uniques[i])) / data.length); - } - - let entropy = 0, - p; - - for (i = 0; i < prob.length; i++) { - p = prob[i]; - entropy += p * Math.log(p) / Math.log(2); - } - - return -entropy; - }, - -}; - -export default Entropy; diff --git a/src/core/operations/legacy/FileType.js b/src/core/operations/legacy/FileType.js deleted file mode 100755 index b9d399cd..00000000 --- a/src/core/operations/legacy/FileType.js +++ /dev/null @@ -1,542 +0,0 @@ -import Utils from "../Utils.js"; - - -/** - * File type operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const FileType = { - - /** - * Detect File Type operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runDetect: function(input, args) { - const data = new Uint8Array(input), - type = FileType.magicType(data); - - if (!type) { - return "Unknown file type. Have you tried checking the entropy of this data to determine whether it might be encrypted or compressed?"; - } else { - let output = "File extension: " + type.ext + "\n" + - "MIME type: " + type.mime; - - if (type.desc && type.desc.length) { - output += "\nDescription: " + type.desc; - } - - return output; - } - }, - - - /** - * @constant - * @default - */ - IGNORE_COMMON_BYTE_SEQUENCES: true, - - /** - * Scan for Embedded Files operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runScanForEmbeddedFiles: function(input, args) { - let output = "Scanning data for 'magic bytes' which may indicate embedded files. The following results may be false positives and should not be treat as reliable. Any suffiently long file is likely to contain these magic bytes coincidentally.\n", - type, - numFound = 0, - numCommonFound = 0; - const ignoreCommon = args[0], - commonExts = ["ico", "ttf", ""], - data = new Uint8Array(input); - - for (let i = 0; i < data.length; i++) { - type = FileType.magicType(data.slice(i)); - if (type) { - if (ignoreCommon && commonExts.indexOf(type.ext) > -1) { - numCommonFound++; - continue; - } - numFound++; - output += "\nOffset " + i + " (0x" + Utils.hex(i) + "):\n" + - " File extension: " + type.ext + "\n" + - " MIME type: " + type.mime + "\n"; - - if (type.desc && type.desc.length) { - output += " Description: " + type.desc + "\n"; - } - } - } - - if (numFound === 0) { - output += "\nNo embedded files were found."; - } - - if (numCommonFound > 0) { - output += "\n\n" + numCommonFound; - output += numCommonFound === 1 ? - " file type was detected that has a common byte sequence. This is likely to be a false positive." : - " file types were detected that have common byte sequences. These are likely to be false positives."; - output += " Run this operation with the 'Ignore common byte sequences' option unchecked to see details."; - } - - return output; - }, - - - /** - * Given a buffer, detects magic byte sequences at specific positions and returns the - * extension and mime type. - * - * @param {Uint8Array} buf - * @returns {Object} type - * @returns {string} type.ext - File extension - * @returns {string} type.mime - Mime type - * @returns {string} [type.desc] - Description - */ - magicType: function (buf) { - if (!(buf && buf.length > 1)) { - return null; - } - - if (buf[0] === 0xFF && buf[1] === 0xD8 && buf[2] === 0xFF) { - return { - ext: "jpg", - mime: "image/jpeg" - }; - } - - if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4E && buf[3] === 0x47) { - return { - ext: "png", - mime: "image/png" - }; - } - - if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46) { - return { - ext: "gif", - mime: "image/gif" - }; - } - - if (buf[8] === 0x57 && buf[9] === 0x45 && buf[10] === 0x42 && buf[11] === 0x50) { - return { - ext: "webp", - mime: "image/webp" - }; - } - - // needs to be before `tif` check - if (((buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0x2A && buf[3] === 0x0) || (buf[0] === 0x4D && buf[1] === 0x4D && buf[2] === 0x0 && buf[3] === 0x2A)) && buf[8] === 0x43 && buf[9] === 0x52) { - return { - ext: "cr2", - mime: "image/x-canon-cr2" - }; - } - - if ((buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0x2A && buf[3] === 0x0) || (buf[0] === 0x4D && buf[1] === 0x4D && buf[2] === 0x0 && buf[3] === 0x2A)) { - return { - ext: "tif", - mime: "image/tiff" - }; - } - - if (buf[0] === 0x42 && buf[1] === 0x4D) { - return { - ext: "bmp", - mime: "image/bmp" - }; - } - - if (buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0xBC) { - return { - ext: "jxr", - mime: "image/vnd.ms-photo" - }; - } - - if (buf[0] === 0x38 && buf[1] === 0x42 && buf[2] === 0x50 && buf[3] === 0x53) { - return { - ext: "psd", - mime: "image/vnd.adobe.photoshop" - }; - } - - // needs to be before `zip` check - if (buf[0] === 0x50 && buf[1] === 0x4B && buf[2] === 0x3 && buf[3] === 0x4 && buf[30] === 0x6D && buf[31] === 0x69 && buf[32] === 0x6D && buf[33] === 0x65 && buf[34] === 0x74 && buf[35] === 0x79 && buf[36] === 0x70 && buf[37] === 0x65 && buf[38] === 0x61 && buf[39] === 0x70 && buf[40] === 0x70 && buf[41] === 0x6C && buf[42] === 0x69 && buf[43] === 0x63 && buf[44] === 0x61 && buf[45] === 0x74 && buf[46] === 0x69 && buf[47] === 0x6F && buf[48] === 0x6E && buf[49] === 0x2F && buf[50] === 0x65 && buf[51] === 0x70 && buf[52] === 0x75 && buf[53] === 0x62 && buf[54] === 0x2B && buf[55] === 0x7A && buf[56] === 0x69 && buf[57] === 0x70) { - return { - ext: "epub", - mime: "application/epub+zip" - }; - } - - if (buf[0] === 0x50 && buf[1] === 0x4B && (buf[2] === 0x3 || buf[2] === 0x5 || buf[2] === 0x7) && (buf[3] === 0x4 || buf[3] === 0x6 || buf[3] === 0x8)) { - return { - ext: "zip", - mime: "application/zip" - }; - } - - if (buf[257] === 0x75 && buf[258] === 0x73 && buf[259] === 0x74 && buf[260] === 0x61 && buf[261] === 0x72) { - return { - ext: "tar", - mime: "application/x-tar" - }; - } - - if (buf[0] === 0x52 && buf[1] === 0x61 && buf[2] === 0x72 && buf[3] === 0x21 && buf[4] === 0x1A && buf[5] === 0x7 && (buf[6] === 0x0 || buf[6] === 0x1)) { - return { - ext: "rar", - mime: "application/x-rar-compressed" - }; - } - - if (buf[0] === 0x1F && buf[1] === 0x8B && buf[2] === 0x8) { - return { - ext: "gz", - mime: "application/gzip" - }; - } - - if (buf[0] === 0x42 && buf[1] === 0x5A && buf[2] === 0x68) { - return { - ext: "bz2", - mime: "application/x-bzip2" - }; - } - - if (buf[0] === 0x37 && buf[1] === 0x7A && buf[2] === 0xBC && buf[3] === 0xAF && buf[4] === 0x27 && buf[5] === 0x1C) { - return { - ext: "7z", - mime: "application/x-7z-compressed" - }; - } - - if (buf[0] === 0x78 && buf[1] === 0x01) { - return { - ext: "dmg, zlib", - mime: "application/x-apple-diskimage, application/x-deflate" - }; - } - - if ((buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && (buf[3] === 0x18 || buf[3] === 0x20) && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70) || (buf[0] === 0x33 && buf[1] === 0x67 && buf[2] === 0x70 && buf[3] === 0x35) || (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1C && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x6D && buf[9] === 0x70 && buf[10] === 0x34 && buf[11] === 0x32 && buf[16] === 0x6D && buf[17] === 0x70 && buf[18] === 0x34 && buf[19] === 0x31 && buf[20] === 0x6D && buf[21] === 0x70 && buf[22] === 0x34 && buf[23] === 0x32 && buf[24] === 0x69 && buf[25] === 0x73 && buf[26] === 0x6F && buf[27] === 0x6D)) { - return { - ext: "mp4", - mime: "video/mp4" - }; - } - - if ((buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1C && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x4D && buf[9] === 0x34 && buf[10] === 0x56)) { - return { - ext: "m4v", - mime: "video/x-m4v" - }; - } - - if (buf[0] === 0x4D && buf[1] === 0x54 && buf[2] === 0x68 && buf[3] === 0x64) { - return { - ext: "mid", - mime: "audio/midi" - }; - } - - // needs to be before the `webm` check - if (buf[31] === 0x6D && buf[32] === 0x61 && buf[33] === 0x74 && buf[34] === 0x72 && buf[35] === 0x6f && buf[36] === 0x73 && buf[37] === 0x6B && buf[38] === 0x61) { - return { - ext: "mkv", - mime: "video/x-matroska" - }; - } - - if (buf[0] === 0x1A && buf[1] === 0x45 && buf[2] === 0xDF && buf[3] === 0xA3) { - return { - ext: "webm", - mime: "video/webm" - }; - } - - if (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x14 && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70) { - return { - ext: "mov", - mime: "video/quicktime" - }; - } - - if (buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 && buf[8] === 0x41 && buf[9] === 0x56 && buf[10] === 0x49) { - return { - ext: "avi", - mime: "video/x-msvideo" - }; - } - - if (buf[0] === 0x30 && buf[1] === 0x26 && buf[2] === 0xB2 && buf[3] === 0x75 && buf[4] === 0x8E && buf[5] === 0x66 && buf[6] === 0xCF && buf[7] === 0x11 && buf[8] === 0xA6 && buf[9] === 0xD9) { - return { - ext: "wmv", - mime: "video/x-ms-wmv" - }; - } - - if (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x1 && buf[3].toString(16)[0] === "b") { - return { - ext: "mpg", - mime: "video/mpeg" - }; - } - - if ((buf[0] === 0x49 && buf[1] === 0x44 && buf[2] === 0x33) || (buf[0] === 0xFF && buf[1] === 0xfb)) { - return { - ext: "mp3", - mime: "audio/mpeg" - }; - } - - if ((buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x4D && buf[9] === 0x34 && buf[10] === 0x41) || (buf[0] === 0x4D && buf[1] === 0x34 && buf[2] === 0x41 && buf[3] === 0x20)) { - return { - ext: "m4a", - mime: "audio/m4a" - }; - } - - if (buf[0] === 0x4F && buf[1] === 0x67 && buf[2] === 0x67 && buf[3] === 0x53) { - return { - ext: "ogg", - mime: "audio/ogg" - }; - } - - if (buf[0] === 0x66 && buf[1] === 0x4C && buf[2] === 0x61 && buf[3] === 0x43) { - return { - ext: "flac", - mime: "audio/x-flac" - }; - } - - if (buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 && buf[8] === 0x57 && buf[9] === 0x41 && buf[10] === 0x56 && buf[11] === 0x45) { - return { - ext: "wav", - mime: "audio/x-wav" - }; - } - - if (buf[0] === 0x23 && buf[1] === 0x21 && buf[2] === 0x41 && buf[3] === 0x4D && buf[4] === 0x52 && buf[5] === 0x0A) { - return { - ext: "amr", - mime: "audio/amr" - }; - } - - if (buf[0] === 0x25 && buf[1] === 0x50 && buf[2] === 0x44 && buf[3] === 0x46) { - return { - ext: "pdf", - mime: "application/pdf" - }; - } - - if (buf[0] === 0x4D && buf[1] === 0x5A) { - return { - ext: "exe", - mime: "application/x-msdownload" - }; - } - - if ((buf[0] === 0x43 || buf[0] === 0x46) && buf[1] === 0x57 && buf[2] === 0x53) { - return { - ext: "swf", - mime: "application/x-shockwave-flash" - }; - } - - if (buf[0] === 0x7B && buf[1] === 0x5C && buf[2] === 0x72 && buf[3] === 0x74 && buf[4] === 0x66) { - return { - ext: "rtf", - mime: "application/rtf" - }; - } - - if (buf[0] === 0x77 && buf[1] === 0x4F && buf[2] === 0x46 && buf[3] === 0x46 && buf[4] === 0x00 && buf[5] === 0x01 && buf[6] === 0x00 && buf[7] === 0x00) { - return { - ext: "woff", - mime: "application/font-woff" - }; - } - - if (buf[0] === 0x77 && buf[1] === 0x4F && buf[2] === 0x46 && buf[3] === 0x32 && buf[4] === 0x00 && buf[5] === 0x01 && buf[6] === 0x00 && buf[7] === 0x00) { - return { - ext: "woff2", - mime: "application/font-woff" - }; - } - - if (buf[34] === 0x4C && buf[35] === 0x50 && ((buf[8] === 0x02 && buf[9] === 0x00 && buf[10] === 0x01) || (buf[8] === 0x01 && buf[9] === 0x00 && buf[10] === 0x00) || (buf[8] === 0x02 && buf[9] === 0x00 && buf[10] === 0x02))) { - return { - ext: "eot", - mime: "application/octet-stream" - }; - } - - if (buf[0] === 0x00 && buf[1] === 0x01 && buf[2] === 0x00 && buf[3] === 0x00 && buf[4] === 0x00) { - return { - ext: "ttf", - mime: "application/font-sfnt" - }; - } - - if (buf[0] === 0x4F && buf[1] === 0x54 && buf[2] === 0x54 && buf[3] === 0x4F && buf[4] === 0x00) { - return { - ext: "otf", - mime: "application/font-sfnt" - }; - } - - if (buf[0] === 0x00 && buf[1] === 0x00 && buf[2] === 0x01 && buf[3] === 0x00) { - return { - ext: "ico", - mime: "image/x-icon" - }; - } - - if (buf[0] === 0x46 && buf[1] === 0x4C && buf[2] === 0x56 && buf[3] === 0x01) { - return { - ext: "flv", - mime: "video/x-flv" - }; - } - - if (buf[0] === 0x25 && buf[1] === 0x21) { - return { - ext: "ps", - mime: "application/postscript" - }; - } - - if (buf[0] === 0xFD && buf[1] === 0x37 && buf[2] === 0x7A && buf[3] === 0x58 && buf[4] === 0x5A && buf[5] === 0x00) { - return { - ext: "xz", - mime: "application/x-xz" - }; - } - - if (buf[0] === 0x53 && buf[1] === 0x51 && buf[2] === 0x4C && buf[3] === 0x69) { - return { - ext: "sqlite", - mime: "application/x-sqlite3" - }; - } - - /** - * - * Added by n1474335 [n1474335@gmail.com] from here on - * - */ - if ((buf[0] === 0x1F && buf[1] === 0x9D) || (buf[0] === 0x1F && buf[1] === 0xA0)) { - return { - ext: "z, tar.z", - mime: "application/x-gtar" - }; - } - - if (buf[0] === 0x7F && buf[1] === 0x45 && buf[2] === 0x4C && buf[3] === 0x46) { - return { - ext: "none, axf, bin, elf, o, prx, puff, so", - mime: "application/x-executable", - desc: "Executable and Linkable Format file. No standard file extension." - }; - } - - if (buf[0] === 0xCA && buf[1] === 0xFE && buf[2] === 0xBA && buf[3] === 0xBE) { - return { - ext: "class", - mime: "application/java-vm" - }; - } - - if (buf[0] === 0xEF && buf[1] === 0xBB && buf[2] === 0xBF) { - return { - ext: "txt", - mime: "text/plain", - desc: "UTF-8 encoded Unicode byte order mark detected, commonly but not exclusively seen in text files." - }; - } - - // Must be before Little-endian UTF-16 BOM - if (buf[0] === 0xFF && buf[1] === 0xFE && buf[2] === 0x00 && buf[3] === 0x00) { - return { - ext: "UTF32LE", - mime: "charset/utf32le", - desc: "Little-endian UTF-32 encoded Unicode byte order mark detected." - }; - } - - if (buf[0] === 0xFF && buf[1] === 0xFE) { - return { - ext: "UTF16LE", - mime: "charset/utf16le", - desc: "Little-endian UTF-16 encoded Unicode byte order mark detected." - }; - } - - if ((buf[0x8001] === 0x43 && buf[0x8002] === 0x44 && buf[0x8003] === 0x30 && buf[0x8004] === 0x30 && buf[0x8005] === 0x31) || - (buf[0x8801] === 0x43 && buf[0x8802] === 0x44 && buf[0x8803] === 0x30 && buf[0x8804] === 0x30 && buf[0x8805] === 0x31) || - (buf[0x9001] === 0x43 && buf[0x9002] === 0x44 && buf[0x9003] === 0x30 && buf[0x9004] === 0x30 && buf[0x9005] === 0x31)) { - return { - ext: "iso", - mime: "application/octet-stream", - desc: "ISO 9660 CD/DVD image file" - }; - } - - if (buf[0] === 0xD0 && buf[1] === 0xCF && buf[2] === 0x11 && buf[3] === 0xE0 && buf[4] === 0xA1 && buf[5] === 0xB1 && buf[6] === 0x1A && buf[7] === 0xE1) { - return { - ext: "doc, xls, ppt", - mime: "application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint", - desc: "Microsoft Office documents" - }; - } - - if (buf[0] === 0x64 && buf[1] === 0x65 && buf[2] === 0x78 && buf[3] === 0x0A && buf[4] === 0x30 && buf[5] === 0x33 && buf[6] === 0x35 && buf[7] === 0x00) { - return { - ext: "dex", - mime: "application/octet-stream", - desc: "Dalvik Executable (Android)" - }; - } - - if (buf[0] === 0x4B && buf[1] === 0x44 && buf[2] === 0x4D) { - return { - ext: "vmdk", - mime: "application/vmdk, application/x-virtualbox-vmdk" - }; - } - - if (buf[0] === 0x43 && buf[1] === 0x72 && buf[2] === 0x32 && buf[3] === 0x34) { - return { - ext: "crx", - mime: "application/crx", - desc: "Google Chrome extension or packaged app" - }; - } - - if (buf[0] === 0x78 && (buf[1] === 0x01 || buf[1] === 0x9C || buf[1] === 0xDA || buf[1] === 0x5e)) { - return { - ext: "zlib", - mime: "application/x-deflate" - }; - } - - return null; - }, - -}; - -export default FileType; diff --git a/src/core/operations/legacy/Filetime.js b/src/core/operations/legacy/Filetime.js deleted file mode 100644 index 9a21088d..00000000 --- a/src/core/operations/legacy/Filetime.js +++ /dev/null @@ -1,103 +0,0 @@ -import BigNumber from "bignumber.js"; - -/** - * Windows Filetime operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2017 - * @license Apache-2.0 - * - * @namespace - */ -const Filetime = { - - /** - * @constant - * @default - */ - UNITS: ["Seconds (s)", "Milliseconds (ms)", "Microseconds (μs)", "Nanoseconds (ns)"], - - /** - * @constant - * @default - */ - FILETIME_FORMATS: ["Decimal", "Hex"], - - /** - * Windows Filetime to Unix Timestamp operation. - * - * @author bwhitn [brian.m.whitney@outlook.com] - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runFromFiletimeToUnix: function(input, args) { - let units = args[0], - format = args[1]; - - if (!input) return ""; - - if (format === "Hex") { - input = new BigNumber(input, 16); - } else { - input = new BigNumber(input); - } - - input = input.minus(new BigNumber("116444736000000000")); - - if (units === "Seconds (s)"){ - input = input.dividedBy(new BigNumber("10000000")); - } else if (units === "Milliseconds (ms)") { - input = input.dividedBy(new BigNumber("10000")); - } else if (units === "Microseconds (μs)") { - input = input.dividedBy(new BigNumber("10")); - } else if (units === "Nanoseconds (ns)") { - input = input.multipliedBy(new BigNumber("100")); - } else { - throw "Unrecognised unit"; - } - - return input.toFixed(); - }, - - - /** - * Unix Timestamp to Windows Filetime operation. - * - * @author bwhitn [brian.m.whitney@outlook.com] - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runToFiletimeFromUnix: function(input, args) { - let units = args[0], - format = args[1]; - - if (!input) return ""; - - input = new BigNumber(input); - - if (units === "Seconds (s)"){ - input = input.multipliedBy(new BigNumber("10000000")); - } else if (units === "Milliseconds (ms)") { - input = input.multipliedBy(new BigNumber("10000")); - } else if (units === "Microseconds (μs)") { - input = input.multiplyiedBy(new BigNumber("10")); - } else if (units === "Nanoseconds (ns)") { - input = input.dividedBy(new BigNumber("100")); - } else { - throw "Unrecognised unit"; - } - - input = input.plus(new BigNumber("116444736000000000")); - - if (format === "Hex"){ - return input.toString(16); - } else { - return input.toFixed(); - } - }, - -}; - -export default Filetime; diff --git a/src/core/operations/legacy/HTML.js b/src/core/operations/legacy/HTML.js deleted file mode 100755 index b1f7e065..00000000 --- a/src/core/operations/legacy/HTML.js +++ /dev/null @@ -1,857 +0,0 @@ -import Utils from "../Utils.js"; - - -/** - * HTML operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const HTML = { - - /** - * @constant - * @default - */ - CONVERT_ALL: false, - /** - * @constant - * @default - */ - CONVERT_OPTIONS: ["Named entities where possible", "Numeric entities", "Hex entities"], - - /** - * To HTML Entity operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runToEntity: function(input, args) { - let convertAll = args[0], - numeric = args[1] === "Numeric entities", - hexa = args[1] === "Hex entities"; - - const charcodes = Utils.strToCharcode(input); - let output = ""; - - for (let i = 0; i < charcodes.length; i++) { - if (convertAll && numeric) { - output += "&#" + charcodes[i] + ";"; - } else if (convertAll && hexa) { - output += "&#x" + Utils.hex(charcodes[i]) + ";"; - } else if (convertAll) { - output += HTML._byteToEntity[charcodes[i]] || "&#" + charcodes[i] + ";"; - } else if (numeric) { - if (charcodes[i] > 255 || HTML._byteToEntity.hasOwnProperty(charcodes[i])) { - output += "&#" + charcodes[i] + ";"; - } else { - output += Utils.chr(charcodes[i]); - } - } else if (hexa) { - if (charcodes[i] > 255 || HTML._byteToEntity.hasOwnProperty(charcodes[i])) { - output += "&#x" + Utils.hex(charcodes[i]) + ";"; - } else { - output += Utils.chr(charcodes[i]); - } - } else { - output += HTML._byteToEntity[charcodes[i]] || ( - charcodes[i] > 255 ? - "&#" + charcodes[i] + ";" : - Utils.chr(charcodes[i]) - ); - } - } - return output; - }, - - - /** - * From HTML Entity operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runFromEntity: function(input, args) { - let regex = /&(#?x?[a-zA-Z0-9]{1,8});/g, - output = "", - m, - i = 0; - - while ((m = regex.exec(input))) { - // Add up to match - for (; i < m.index;) - output += input[i++]; - - // Add match - const bite = HTML._entityToByte[m[1]]; - if (bite) { - output += Utils.chr(bite); - } else if (!bite && m[1][0] === "#" && m[1].length > 1 && /^#\d{1,6}$/.test(m[1])) { - // Numeric entity (e.g. ) - const num = m[1].slice(1, m[1].length); - output += Utils.chr(parseInt(num, 10)); - } else if (!bite && m[1][0] === "#" && m[1].length > 3 && /^#x[\dA-F]{2,8}$/i.test(m[1])) { - // Hex entity (e.g. :) - const hex = m[1].slice(2, m[1].length); - output += Utils.chr(parseInt(hex, 16)); - } else { - // Not a valid entity, print as normal - for (; i < regex.lastIndex;) - output += input[i++]; - } - - i = regex.lastIndex; - } - // Add all after final match - for (; i < input.length;) - output += input[i++]; - - return output; - }, - - - /** - * @constant - * @default - */ - REMOVE_INDENTATION: true, - /** - * @constant - * @default - */ - REMOVE_LINE_BREAKS: true, - - /** - * Strip HTML tags operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runStripTags: function(input, args) { - let removeIndentation = args[0], - removeLineBreaks = args[1]; - - input = Utils.stripHtmlTags(input); - - if (removeIndentation) { - input = input.replace(/\n[ \f\t]+/g, "\n"); - } - - if (removeLineBreaks) { - input = input - .replace(/^\s*\n/, "") // first line - .replace(/(\n\s*){2,}/g, "\n"); // all others - } - - return input; - }, - - - /** - * Parse colour code operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {html} - */ - runParseColourCode: function(input, args) { - let m = null, - r = 0, g = 0, b = 0, a = 1; - - // Read in the input - if ((m = input.match(/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/i))) { - // Hex - #d9edf7 - r = parseInt(m[1], 16); - g = parseInt(m[2], 16); - b = parseInt(m[3], 16); - } else if ((m = input.match(/rgba?\((\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?)(?:,\s?(\d(?:\.\d+)?))?\)/i))) { - // RGB or RGBA - rgb(217,237,247) or rgba(217,237,247,1) - r = parseFloat(m[1]); - g = parseFloat(m[2]); - b = parseFloat(m[3]); - a = m[4] ? parseFloat(m[4]) : 1; - } else if ((m = input.match(/hsla?\((\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?)%,\s?(\d{1,3}(?:\.\d+)?)%(?:,\s?(\d(?:\.\d+)?))?\)/i))) { - // HSL or HSLA - hsl(200, 65%, 91%) or hsla(200, 65%, 91%, 1) - let h_ = parseFloat(m[1]) / 360, - s_ = parseFloat(m[2]) / 100, - l_ = parseFloat(m[3]) / 100, - rgb_ = HTML._hslToRgb(h_, s_, l_); - - r = rgb_[0]; - g = rgb_[1]; - b = rgb_[2]; - a = m[4] ? parseFloat(m[4]) : 1; - } else if ((m = input.match(/cmyk\((\d(?:\.\d+)?),\s?(\d(?:\.\d+)?),\s?(\d(?:\.\d+)?),\s?(\d(?:\.\d+)?)\)/i))) { - // CMYK - cmyk(0.12, 0.04, 0.00, 0.03) - let c_ = parseFloat(m[1]), - m_ = parseFloat(m[2]), - y_ = parseFloat(m[3]), - k_ = parseFloat(m[4]); - - r = Math.round(255 * (1 - c_) * (1 - k_)); - g = Math.round(255 * (1 - m_) * (1 - k_)); - b = Math.round(255 * (1 - y_) * (1 - k_)); - } - - let hsl_ = HTML._rgbToHsl(r, g, b), - h = Math.round(hsl_[0] * 360), - s = Math.round(hsl_[1] * 100), - l = Math.round(hsl_[2] * 100), - k = 1 - Math.max(r/255, g/255, b/255), - c = (1 - r/255 - k) / (1 - k), - y = (1 - b/255 - k) / (1 - k); - - m = (1 - g/255 - k) / (1 - k); - - c = isNaN(c) ? "0" : c.toFixed(2); - m = isNaN(m) ? "0" : m.toFixed(2); - y = isNaN(y) ? "0" : y.toFixed(2); - k = k.toFixed(2); - - let hex = "#" + - Math.round(r).toString(16).padStart(2, "0") + - Math.round(g).toString(16).padStart(2, "0") + - Math.round(b).toString(16).padStart(2, "0"), - rgb = "rgb(" + r + ", " + g + ", " + b + ")", - rgba = "rgba(" + r + ", " + g + ", " + b + ", " + a + ")", - hsl = "hsl(" + h + ", " + s + "%, " + l + "%)", - hsla = "hsla(" + h + ", " + s + "%, " + l + "%, " + a + ")", - cmyk = "cmyk(" + c + ", " + m + ", " + y + ", " + k + ")"; - - // Generate output - return `
-Hex: ${hex} -RGB: ${rgb} -RGBA: ${rgba} -HSL: ${hsl} -HSLA: ${hsla} -CMYK: ${cmyk} -`; - }, - - - /** - * Converts an HSL color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSL_colorSpace. - * Assumes h, s, and l are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * @private - * @author Mohsen (http://stackoverflow.com/a/9493060) - * - * @param {number} h - The hue - * @param {number} s - The saturation - * @param {number} l - The lightness - * @return {Array} The RGB representation - */ - _hslToRgb: function(h, s, l){ - let r, g, b; - - if (s === 0){ - r = g = b = l; // achromatic - } else { - const hue2rgb = function hue2rgb(p, q, t) { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1/6) return p + (q - p) * 6 * t; - if (t < 1/2) return q; - if (t < 2/3) return p + (q - p) * (2/3 - t) * 6; - return p; - }; - - const q = l < 0.5 ? l * (1 + s) : l + s - l * s; - const p = 2 * l - q; - r = hue2rgb(p, q, h + 1/3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1/3); - } - - return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; - }, - - - /** - * Converts an RGB color value to HSL. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSL_colorSpace. - * Assumes r, g, and b are contained in the set [0, 255] and - * returns h, s, and l in the set [0, 1]. - * - * @private - * @author Mohsen (http://stackoverflow.com/a/9493060) - * - * @param {number} r - The red color value - * @param {number} g - The green color value - * @param {number} b - The blue color value - * @return {Array} The HSL representation - */ - _rgbToHsl: function(r, g, b) { - r /= 255; g /= 255; b /= 255; - let max = Math.max(r, g, b), - min = Math.min(r, g, b), - h, s, l = (max + min) / 2; - - if (max === min) { - h = s = 0; // achromatic - } else { - const d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - h /= 6; - } - - return [h, s, l]; - }, - - - /** - * Lookup table to translate byte values to their HTML entity codes. - * - * @private - * @constant - */ - _byteToEntity: { - 34: """, - 38: "&", - 39: "'", - 60: "<", - 62: ">", - 160: " ", - 161: "¡", - 162: "¢", - 163: "£", - 164: "¤", - 165: "¥", - 166: "¦", - 167: "§", - 168: "¨", - 169: "©", - 170: "ª", - 171: "«", - 172: "¬", - 173: "­", - 174: "®", - 175: "¯", - 176: "°", - 177: "±", - 178: "²", - 179: "³", - 180: "´", - 181: "µ", - 182: "¶", - 183: "·", - 184: "¸", - 185: "¹", - 186: "º", - 187: "»", - 188: "¼", - 189: "½", - 190: "¾", - 191: "¿", - 192: "À", - 193: "Á", - 194: "Â", - 195: "Ã", - 196: "Ä", - 197: "Å", - 198: "Æ", - 199: "Ç", - 200: "È", - 201: "É", - 202: "Ê", - 203: "Ë", - 204: "Ì", - 205: "Í", - 206: "Î", - 207: "Ï", - 208: "Ð", - 209: "Ñ", - 210: "Ò", - 211: "Ó", - 212: "Ô", - 213: "Õ", - 214: "Ö", - 215: "×", - 216: "Ø", - 217: "Ù", - 218: "Ú", - 219: "Û", - 220: "Ü", - 221: "Ý", - 222: "Þ", - 223: "ß", - 224: "à", - 225: "á", - 226: "â", - 227: "ã", - 228: "ä", - 229: "å", - 230: "æ", - 231: "ç", - 232: "è", - 233: "é", - 234: "ê", - 235: "ë", - 236: "ì", - 237: "í", - 238: "î", - 239: "ï", - 240: "ð", - 241: "ñ", - 242: "ò", - 243: "ó", - 244: "ô", - 245: "õ", - 246: "ö", - 247: "÷", - 248: "ø", - 249: "ù", - 250: "ú", - 251: "û", - 252: "ü", - 253: "ý", - 254: "þ", - 255: "ÿ", - 338: "Œ", - 339: "œ", - 352: "Š", - 353: "š", - 376: "Ÿ", - 402: "ƒ", - 710: "ˆ", - 732: "˜", - 913: "Α", - 914: "Β", - 915: "Γ", - 916: "Δ", - 917: "Ε", - 918: "Ζ", - 919: "Η", - 920: "Θ", - 921: "Ι", - 922: "Κ", - 923: "Λ", - 924: "Μ", - 925: "Ν", - 926: "Ξ", - 927: "Ο", - 928: "Π", - 929: "Ρ", - 931: "Σ", - 932: "Τ", - 933: "Υ", - 934: "Φ", - 935: "Χ", - 936: "Ψ", - 937: "Ω", - 945: "α", - 946: "β", - 947: "γ", - 948: "δ", - 949: "ε", - 950: "ζ", - 951: "η", - 952: "θ", - 953: "ι", - 954: "κ", - 955: "λ", - 956: "μ", - 957: "ν", - 958: "ξ", - 959: "ο", - 960: "π", - 961: "ρ", - 962: "ς", - 963: "σ", - 964: "τ", - 965: "υ", - 966: "φ", - 967: "χ", - 968: "ψ", - 969: "ω", - 977: "ϑ", - 978: "ϒ", - 982: "ϖ", - 8194: " ", - 8195: " ", - 8201: " ", - 8204: "‌", - 8205: "‍", - 8206: "‎", - 8207: "‏", - 8211: "–", - 8212: "—", - 8216: "‘", - 8217: "’", - 8218: "‚", - 8220: "“", - 8221: "”", - 8222: "„", - 8224: "†", - 8225: "‡", - 8226: "•", - 8230: "…", - 8240: "‰", - 8242: "′", - 8243: "″", - 8249: "‹", - 8250: "›", - 8254: "‾", - 8260: "⁄", - 8364: "€", - 8465: "ℑ", - 8472: "℘", - 8476: "ℜ", - 8482: "™", - 8501: "ℵ", - 8592: "←", - 8593: "↑", - 8594: "→", - 8595: "↓", - 8596: "↔", - 8629: "↵", - 8656: "⇐", - 8657: "⇑", - 8658: "⇒", - 8659: "⇓", - 8660: "⇔", - 8704: "∀", - 8706: "∂", - 8707: "∃", - 8709: "∅", - 8711: "∇", - 8712: "∈", - 8713: "∉", - 8715: "∋", - 8719: "∏", - 8721: "∑", - 8722: "−", - 8727: "∗", - 8730: "√", - 8733: "∝", - 8734: "∞", - 8736: "∠", - 8743: "∧", - 8744: "∨", - 8745: "∩", - 8746: "∪", - 8747: "∫", - 8756: "∴", - 8764: "∼", - 8773: "≅", - 8776: "≈", - 8800: "≠", - 8801: "≡", - 8804: "≤", - 8805: "≥", - 8834: "⊂", - 8835: "⊃", - 8836: "⊄", - 8838: "⊆", - 8839: "⊇", - 8853: "⊕", - 8855: "⊗", - 8869: "⊥", - 8901: "⋅", - 8942: "⋮", - 8968: "⌈", - 8969: "⌉", - 8970: "⌊", - 8971: "⌋", - 9001: "⟨", - 9002: "⟩", - 9674: "◊", - 9824: "♠", - 9827: "♣", - 9829: "♥", - 9830: "♦", - }, - - - /** - * Lookup table to translate HTML entity codes to their byte values. - * - * @private - * @constant - */ - _entityToByte: { - "quot": 34, - "amp": 38, - "apos": 39, - "lt": 60, - "gt": 62, - "nbsp": 160, - "iexcl": 161, - "cent": 162, - "pound": 163, - "curren": 164, - "yen": 165, - "brvbar": 166, - "sect": 167, - "uml": 168, - "copy": 169, - "ordf": 170, - "laquo": 171, - "not": 172, - "shy": 173, - "reg": 174, - "macr": 175, - "deg": 176, - "plusmn": 177, - "sup2": 178, - "sup3": 179, - "acute": 180, - "micro": 181, - "para": 182, - "middot": 183, - "cedil": 184, - "sup1": 185, - "ordm": 186, - "raquo": 187, - "frac14": 188, - "frac12": 189, - "frac34": 190, - "iquest": 191, - "Agrave": 192, - "Aacute": 193, - "Acirc": 194, - "Atilde": 195, - "Auml": 196, - "Aring": 197, - "AElig": 198, - "Ccedil": 199, - "Egrave": 200, - "Eacute": 201, - "Ecirc": 202, - "Euml": 203, - "Igrave": 204, - "Iacute": 205, - "Icirc": 206, - "Iuml": 207, - "ETH": 208, - "Ntilde": 209, - "Ograve": 210, - "Oacute": 211, - "Ocirc": 212, - "Otilde": 213, - "Ouml": 214, - "times": 215, - "Oslash": 216, - "Ugrave": 217, - "Uacute": 218, - "Ucirc": 219, - "Uuml": 220, - "Yacute": 221, - "THORN": 222, - "szlig": 223, - "agrave": 224, - "aacute": 225, - "acirc": 226, - "atilde": 227, - "auml": 228, - "aring": 229, - "aelig": 230, - "ccedil": 231, - "egrave": 232, - "eacute": 233, - "ecirc": 234, - "euml": 235, - "igrave": 236, - "iacute": 237, - "icirc": 238, - "iuml": 239, - "eth": 240, - "ntilde": 241, - "ograve": 242, - "oacute": 243, - "ocirc": 244, - "otilde": 245, - "ouml": 246, - "divide": 247, - "oslash": 248, - "ugrave": 249, - "uacute": 250, - "ucirc": 251, - "uuml": 252, - "yacute": 253, - "thorn": 254, - "yuml": 255, - "OElig": 338, - "oelig": 339, - "Scaron": 352, - "scaron": 353, - "Yuml": 376, - "fnof": 402, - "circ": 710, - "tilde": 732, - "Alpha": 913, - "Beta": 914, - "Gamma": 915, - "Delta": 916, - "Epsilon": 917, - "Zeta": 918, - "Eta": 919, - "Theta": 920, - "Iota": 921, - "Kappa": 922, - "Lambda": 923, - "Mu": 924, - "Nu": 925, - "Xi": 926, - "Omicron": 927, - "Pi": 928, - "Rho": 929, - "Sigma": 931, - "Tau": 932, - "Upsilon": 933, - "Phi": 934, - "Chi": 935, - "Psi": 936, - "Omega": 937, - "alpha": 945, - "beta": 946, - "gamma": 947, - "delta": 948, - "epsilon": 949, - "zeta": 950, - "eta": 951, - "theta": 952, - "iota": 953, - "kappa": 954, - "lambda": 955, - "mu": 956, - "nu": 957, - "xi": 958, - "omicron": 959, - "pi": 960, - "rho": 961, - "sigmaf": 962, - "sigma": 963, - "tau": 964, - "upsilon": 965, - "phi": 966, - "chi": 967, - "psi": 968, - "omega": 969, - "thetasym": 977, - "upsih": 978, - "piv": 982, - "ensp": 8194, - "emsp": 8195, - "thinsp": 8201, - "zwnj": 8204, - "zwj": 8205, - "lrm": 8206, - "rlm": 8207, - "ndash": 8211, - "mdash": 8212, - "lsquo": 8216, - "rsquo": 8217, - "sbquo": 8218, - "ldquo": 8220, - "rdquo": 8221, - "bdquo": 8222, - "dagger": 8224, - "Dagger": 8225, - "bull": 8226, - "hellip": 8230, - "permil": 8240, - "prime": 8242, - "Prime": 8243, - "lsaquo": 8249, - "rsaquo": 8250, - "oline": 8254, - "frasl": 8260, - "euro": 8364, - "image": 8465, - "weierp": 8472, - "real": 8476, - "trade": 8482, - "alefsym": 8501, - "larr": 8592, - "uarr": 8593, - "rarr": 8594, - "darr": 8595, - "harr": 8596, - "crarr": 8629, - "lArr": 8656, - "uArr": 8657, - "rArr": 8658, - "dArr": 8659, - "hArr": 8660, - "forall": 8704, - "part": 8706, - "exist": 8707, - "empty": 8709, - "nabla": 8711, - "isin": 8712, - "notin": 8713, - "ni": 8715, - "prod": 8719, - "sum": 8721, - "minus": 8722, - "lowast": 8727, - "radic": 8730, - "prop": 8733, - "infin": 8734, - "ang": 8736, - "and": 8743, - "or": 8744, - "cap": 8745, - "cup": 8746, - "int": 8747, - "there4": 8756, - "sim": 8764, - "cong": 8773, - "asymp": 8776, - "ne": 8800, - "equiv": 8801, - "le": 8804, - "ge": 8805, - "sub": 8834, - "sup": 8835, - "nsub": 8836, - "sube": 8838, - "supe": 8839, - "oplus": 8853, - "otimes": 8855, - "perp": 8869, - "sdot": 8901, - "vellip": 8942, - "lceil": 8968, - "rceil": 8969, - "lfloor": 8970, - "rfloor": 8971, - "lang": 9001, - "rang": 9002, - "loz": 9674, - "spades": 9824, - "clubs": 9827, - "hearts": 9829, - "diams": 9830, - }, - -}; - -export default HTML; diff --git a/src/core/operations/legacy/HTTP.js b/src/core/operations/legacy/HTTP.js deleted file mode 100755 index dcb1cc50..00000000 --- a/src/core/operations/legacy/HTTP.js +++ /dev/null @@ -1,158 +0,0 @@ -import UAParser from "ua-parser-js"; - - -/** - * HTTP operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const HTTP = { - - /** - * @constant - * @default - */ - METHODS: [ - "GET", "POST", "HEAD", - "PUT", "PATCH", "DELETE", - "CONNECT", "TRACE", "OPTIONS" - ], - - - /** - * Strip HTTP headers operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runStripHeaders: function(input, args) { - let headerEnd = input.indexOf("\r\n\r\n"); - headerEnd = (headerEnd < 0) ? input.indexOf("\n\n") + 2 : headerEnd + 4; - - return (headerEnd < 2) ? input : input.slice(headerEnd, input.length); - }, - - - /** - * Parse User Agent operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runParseUserAgent: function(input, args) { - const ua = UAParser(input); - return `Browser - Name: ${ua.browser.name || "unknown"} - Version: ${ua.browser.version || "unknown"} -Device - Model: ${ua.device.model || "unknown"} - Type: ${ua.device.type || "unknown"} - Vendor: ${ua.device.vendor || "unknown"} -Engine - Name: ${ua.engine.name || "unknown"} - Version: ${ua.engine.version || "unknown"} -OS - Name: ${ua.os.name || "unknown"} - Version: ${ua.os.version || "unknown"} -CPU - Architecture: ${ua.cpu.architecture || "unknown"}`; - }, - - - /** - * @constant - * @default - */ - MODE: [ - "Cross-Origin Resource Sharing", - "No CORS (limited to HEAD, GET or POST)", - ], - - /** - * Lookup table for HTTP modes - * - * @private - * @constant - */ - _modeLookup: { - "Cross-Origin Resource Sharing": "cors", - "No CORS (limited to HEAD, GET or POST)": "no-cors", - }, - - /** - * HTTP request operation. - * - * @author tlwr [toby@toby.codes] - * @author n1474335 [n1474335@gmail.com] - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runHTTPRequest(input, args) { - const method = args[0], - url = args[1], - headersText = args[2], - mode = args[3], - showResponseMetadata = args[4]; - - if (url.length === 0) return ""; - - let headers = new Headers(); - headersText.split(/\r?\n/).forEach(line => { - line = line.trim(); - - if (line.length === 0) return; - - let split = line.split(":"); - if (split.length !== 2) throw `Could not parse header in line: ${line}`; - - headers.set(split[0].trim(), split[1].trim()); - }); - - let config = { - method: method, - headers: headers, - mode: HTTP._modeLookup[mode], - cache: "no-cache", - }; - - if (method !== "GET" && method !== "HEAD") { - config.body = input; - } - - return fetch(url, config) - .then(r => { - if (r.status === 0 && r.type === "opaque") { - return "Error: Null response. Try setting the connection mode to CORS."; - } - - if (showResponseMetadata) { - let headers = ""; - for (let pair of r.headers.entries()) { - headers += " " + pair[0] + ": " + pair[1] + "\n"; - } - return r.text().then(b => { - return "####\n Status: " + r.status + " " + r.statusText + - "\n Exposed headers:\n" + headers + "####\n\n" + b; - }); - } - return r.text(); - }) - .catch(e => { - return e.toString() + - "\n\nThis error could be caused by one of the following:\n" + - " - An invalid URL\n" + - " - Making a request to an insecure resource (HTTP) from a secure source (HTTPS)\n" + - " - Making a cross-origin request to a server which does not support CORS\n"; - }); - }, - -}; - -export default HTTP; diff --git a/src/core/operations/legacy/Hash.js b/src/core/operations/legacy/Hash.js deleted file mode 100755 index f09f7c75..00000000 --- a/src/core/operations/legacy/Hash.js +++ /dev/null @@ -1,785 +0,0 @@ -import Utils from "../Utils.js"; -import CryptoApi from "babel-loader!crypto-api"; -import MD6 from "node-md6"; -import * as SHA3 from "js-sha3"; -import Checksum from "./Checksum.js"; -import ctph from "ctph.js"; -import ssdeep from "ssdeep.js"; -import bcrypt from "bcryptjs"; -import scrypt from "scryptsy"; - - -/** - * Hashing operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Hash = { - - /** - * Generic hash function. - * - * @param {string} name - * @param {ArrayBuffer} input - * @param {Object} [options={}] - * @returns {string} - */ - runHash: function(name, input, options={}) { - const msg = Utils.arrayBufferToStr(input, false), - hasher = CryptoApi.getHasher(name, options); - hasher.update(msg); - return CryptoApi.encoder.toHex(hasher.finalize()); - }, - - - /** - * MD2 operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runMD2: function (input, args) { - return Hash.runHash("md2", input); - }, - - - /** - * MD4 operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runMD4: function (input, args) { - return Hash.runHash("md4", input); - }, - - - /** - * MD5 operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runMD5: function (input, args) { - return Hash.runHash("md5", input); - }, - - - /** - * @constant - * @default - */ - MD6_SIZE: 256, - /** - * @constant - * @default - */ - MD6_LEVELS: 64, - - /** - * MD6 operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runMD6: function (input, args) { - const size = args[0], - levels = args[1], - key = args[2]; - - if (size < 0 || size > 512) - return "Size must be between 0 and 512"; - if (levels < 0) - return "Levels must be greater than 0"; - - return MD6.getHashOfText(input, size, key, levels); - }, - - - /** - * SHA0 operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runSHA0: function (input, args) { - return Hash.runHash("sha0", input); - }, - - - /** - * SHA1 operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runSHA1: function (input, args) { - return Hash.runHash("sha1", input); - }, - - - /** - * @constant - * @default - */ - SHA2_SIZE: ["512", "256", "384", "224", "512/256", "512/224"], - - /** - * SHA2 operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runSHA2: function (input, args) { - const size = args[0]; - return Hash.runHash("sha" + size, input); - }, - - - /** - * @constant - * @default - */ - SHA3_SIZE: ["512", "384", "256", "224"], - - /** - * SHA3 operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runSHA3: function (input, args) { - const size = parseInt(args[0], 10); - let algo; - - switch (size) { - case 224: - algo = SHA3.sha3_224; - break; - case 384: - algo = SHA3.sha3_384; - break; - case 256: - algo = SHA3.sha3_256; - break; - case 512: - algo = SHA3.sha3_512; - break; - default: - return "Invalid size"; - } - - return algo(input); - }, - - - /** - * @constant - * @default - */ - KECCAK_SIZE: ["512", "384", "256", "224"], - - /** - * Keccak operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runKeccak: function (input, args) { - const size = parseInt(args[0], 10); - let algo; - - switch (size) { - case 224: - algo = SHA3.keccak224; - break; - case 384: - algo = SHA3.keccak384; - break; - case 256: - algo = SHA3.keccak256; - break; - case 512: - algo = SHA3.keccak512; - break; - default: - return "Invalid size"; - } - - return algo(input); - }, - - - /** - * @constant - * @default - */ - SHAKE_CAPACITY: ["256", "128"], - /** - * @constant - * @default - */ - SHAKE_SIZE: 512, - - /** - * Shake operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runShake: function (input, args) { - const capacity = parseInt(args[0], 10), - size = args[1]; - let algo; - - if (size < 0) - return "Size must be greater than 0"; - - switch (capacity) { - case 128: - algo = SHA3.shake128; - break; - case 256: - algo = SHA3.shake256; - break; - default: - return "Invalid size"; - } - - return algo(input, size); - }, - - - /** - * @constant - * @default - */ - RIPEMD_SIZE: ["320", "256", "160", "128"], - - /** - * RIPEMD operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runRIPEMD: function (input, args) { - const size = args[0]; - return Hash.runHash("ripemd" + size, input); - }, - - - /** - * HAS-160 operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runHAS: function (input, args) { - return Hash.runHash("has160", input); - }, - - - /** - * @constant - * @default - */ - WHIRLPOOL_VARIANT: ["Whirlpool", "Whirlpool-T", "Whirlpool-0"], - - /** - * Whirlpool operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runWhirlpool: function (input, args) { - const variant = args[0].toLowerCase(); - return Hash.runHash(variant, input); - }, - - - /** - * @constant - * @default - */ - SNEFRU_ROUNDS: ["8", "4", "2"], - /** - * @constant - * @default - */ - SNEFRU_SIZE: ["256", "128"], - - /** - * Snefru operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runSnefru: function (input, args) { - return Hash.runHash("snefru", input, { - rounds: args[0], - length: args[1] - }); - }, - - - /** - * CTPH operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runCTPH: function (input, args) { - return ctph.digest(input); - }, - - - /** - * SSDEEP operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runSSDEEP: function (input, args) { - return ssdeep.digest(input); - }, - - - /** - * @constant - * @default - */ - DELIM_OPTIONS: ["Line feed", "CRLF", "Space", "Comma"], - - /** - * Compare CTPH hashes operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {Number} - */ - runCompareCTPH: function (input, args) { - const samples = input.split(Utils.charRep(args[0])); - if (samples.length !== 2) throw "Incorrect number of samples."; - return ctph.similarity(samples[0], samples[1]); - }, - - - /** - * Compare SSDEEP hashes operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {Number} - */ - runCompareSSDEEP: function (input, args) { - const samples = input.split(Utils.charRep(args[0])); - if (samples.length !== 2) throw "Incorrect number of samples."; - return ssdeep.similarity(samples[0], samples[1]); - }, - - - /** - * @constant - * @default - */ - HMAC_FUNCTIONS: [ - "MD2", - "MD4", - "MD5", - "SHA0", - "SHA1", - "SHA224", - "SHA256", - "SHA384", - "SHA512", - "SHA512/224", - "SHA512/256", - "RIPEMD128", - "RIPEMD160", - "RIPEMD256", - "RIPEMD320", - "HAS160", - "Whirlpool", - "Whirlpool-0", - "Whirlpool-T", - "Snefru" - ], - - /** - * HMAC operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runHMAC: function (input, args) { - const key = args[0], - hashFunc = args[1].toLowerCase(), - msg = Utils.arrayBufferToStr(input, false), - hasher = CryptoApi.getHasher(hashFunc); - - // Horrible shim to fix constructor bug. Reported in nf404/crypto-api#8 - hasher.reset = () => { - hasher.state = {}; - const tmp = new hasher.constructor(); - hasher.state = tmp.state; - }; - - const mac = CryptoApi.getHmac(CryptoApi.encoder.fromUtf(key), hasher); - mac.update(msg); - return CryptoApi.encoder.toHex(mac.finalize()); - }, - - - /** - * @constant - * @default - */ - BCRYPT_ROUNDS: 10, - - /** - * Bcrypt operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runBcrypt: async function (input, args) { - const rounds = args[0]; - const salt = await bcrypt.genSalt(rounds); - - return await bcrypt.hash(input, salt, null, p => { - // Progress callback - if (ENVIRONMENT_IS_WORKER()) - self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`); - }); - }, - - - /** - * Bcrypt compare operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runBcryptCompare: async function (input, args) { - const hash = args[0]; - - const match = await bcrypt.compare(input, hash, null, p => { - // Progress callback - if (ENVIRONMENT_IS_WORKER()) - self.sendStatusMessage(`Progress: ${(p * 100).toFixed(0)}%`); - }); - - return match ? "Match: " + input : "No match"; - }, - - - /** - * Bcrypt parse operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runBcryptParse: async function (input, args) { - try { - return `Rounds: ${bcrypt.getRounds(input)} -Salt: ${bcrypt.getSalt(input)} -Password hash: ${input.split(bcrypt.getSalt(input))[1]} -Full hash: ${input}`; - } catch (err) { - return "Error: " + err.toString(); - } - }, - - - /** - * @constant - * @default - */ - KEY_FORMAT: ["Hex", "Base64", "UTF8", "Latin1"], - /** - * @constant - * @default - */ - SCRYPT_ITERATIONS: 16384, - /** - * @constant - * @default - */ - SCRYPT_MEM_FACTOR: 8, - /** - * @constant - * @default - */ - SCRYPT_PARALLEL_FACTOR: 1, - /** - * @constant - * @default - */ - SCRYPT_KEY_LENGTH: 64, - - /** - * Scrypt operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runScrypt: function (input, args) { - const salt = Utils.convertToByteString(args[0].string || "", args[0].option), - iterations = args[1], - memFactor = args[2], - parallelFactor = args[3], - keyLength = args[4]; - - try { - const data = scrypt( - input, salt, iterations, memFactor, parallelFactor, keyLength, - p => { - // Progress callback - if (ENVIRONMENT_IS_WORKER()) - self.sendStatusMessage(`Progress: ${p.percent.toFixed(0)}%`); - } - ); - - return data.toString("hex"); - } catch (err) { - return "Error: " + err.toString(); - } - }, - - - /** - * Generate all hashes operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runAll: function (input, args) { - const arrayBuffer = input, - str = Utils.arrayBufferToStr(arrayBuffer, false), - byteArray = new Uint8Array(arrayBuffer), - output = "MD2: " + Hash.runMD2(arrayBuffer, []) + - "\nMD4: " + Hash.runMD4(arrayBuffer, []) + - "\nMD5: " + Hash.runMD5(arrayBuffer, []) + - "\nMD6: " + Hash.runMD6(str, []) + - "\nSHA0: " + Hash.runSHA0(arrayBuffer, []) + - "\nSHA1: " + Hash.runSHA1(arrayBuffer, []) + - "\nSHA2 224: " + Hash.runSHA2(arrayBuffer, ["224"]) + - "\nSHA2 256: " + Hash.runSHA2(arrayBuffer, ["256"]) + - "\nSHA2 384: " + Hash.runSHA2(arrayBuffer, ["384"]) + - "\nSHA2 512: " + Hash.runSHA2(arrayBuffer, ["512"]) + - "\nSHA3 224: " + Hash.runSHA3(arrayBuffer, ["224"]) + - "\nSHA3 256: " + Hash.runSHA3(arrayBuffer, ["256"]) + - "\nSHA3 384: " + Hash.runSHA3(arrayBuffer, ["384"]) + - "\nSHA3 512: " + Hash.runSHA3(arrayBuffer, ["512"]) + - "\nKeccak 224: " + Hash.runKeccak(arrayBuffer, ["224"]) + - "\nKeccak 256: " + Hash.runKeccak(arrayBuffer, ["256"]) + - "\nKeccak 384: " + Hash.runKeccak(arrayBuffer, ["384"]) + - "\nKeccak 512: " + Hash.runKeccak(arrayBuffer, ["512"]) + - "\nShake 128: " + Hash.runShake(arrayBuffer, ["128", 256]) + - "\nShake 256: " + Hash.runShake(arrayBuffer, ["256", 512]) + - "\nRIPEMD-128: " + Hash.runRIPEMD(arrayBuffer, ["128"]) + - "\nRIPEMD-160: " + Hash.runRIPEMD(arrayBuffer, ["160"]) + - "\nRIPEMD-256: " + Hash.runRIPEMD(arrayBuffer, ["256"]) + - "\nRIPEMD-320: " + Hash.runRIPEMD(arrayBuffer, ["320"]) + - "\nHAS-160: " + Hash.runHAS(arrayBuffer, []) + - "\nWhirlpool-0: " + Hash.runWhirlpool(arrayBuffer, ["Whirlpool-0"]) + - "\nWhirlpool-T: " + Hash.runWhirlpool(arrayBuffer, ["Whirlpool-T"]) + - "\nWhirlpool: " + Hash.runWhirlpool(arrayBuffer, ["Whirlpool"]) + - "\nSSDEEP: " + Hash.runSSDEEP(str) + - "\nCTPH: " + Hash.runCTPH(str) + - "\n\nChecksums:" + - "\nFletcher-8: " + Checksum.runFletcher8(byteArray, []) + - "\nFletcher-16: " + Checksum.runFletcher16(byteArray, []) + - "\nFletcher-32: " + Checksum.runFletcher32(byteArray, []) + - "\nFletcher-64: " + Checksum.runFletcher64(byteArray, []) + - "\nAdler-32: " + Checksum.runAdler32(byteArray, []) + - "\nCRC-16: " + Checksum.runCRC16(str, []) + - "\nCRC-32: " + Checksum.runCRC32(str, []); - - return output; - }, - - - /** - * Analyse hash operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runAnalyse: function(input, args) { - input = input.replace(/\s/g, ""); - - let output = "", - byteLength = input.length / 2, - bitLength = byteLength * 8, - possibleHashFunctions = []; - - if (!/^[a-f0-9]+$/i.test(input)) { - return "Invalid hash"; - } - - output += "Hash length: " + input.length + "\n" + - "Byte length: " + byteLength + "\n" + - "Bit length: " + bitLength + "\n\n" + - "Based on the length, this hash could have been generated by one of the following hashing functions:\n"; - - switch (bitLength) { - case 4: - possibleHashFunctions = [ - "Fletcher-4", - "Luhn algorithm", - "Verhoeff algorithm", - ]; - break; - case 8: - possibleHashFunctions = [ - "Fletcher-8", - ]; - break; - case 16: - possibleHashFunctions = [ - "BSD checksum", - "CRC-16", - "SYSV checksum", - "Fletcher-16" - ]; - break; - case 32: - possibleHashFunctions = [ - "CRC-32", - "Fletcher-32", - "Adler-32", - ]; - break; - case 64: - possibleHashFunctions = [ - "CRC-64", - "RIPEMD-64", - "SipHash", - ]; - break; - case 128: - possibleHashFunctions = [ - "MD5", - "MD4", - "MD2", - "HAVAL-128", - "RIPEMD-128", - "Snefru", - "Tiger-128", - ]; - break; - case 160: - possibleHashFunctions = [ - "SHA-1", - "SHA-0", - "FSB-160", - "HAS-160", - "HAVAL-160", - "RIPEMD-160", - "Tiger-160", - ]; - break; - case 192: - possibleHashFunctions = [ - "Tiger", - "HAVAL-192", - ]; - break; - case 224: - possibleHashFunctions = [ - "SHA-224", - "SHA3-224", - "ECOH-224", - "FSB-224", - "HAVAL-224", - ]; - break; - case 256: - possibleHashFunctions = [ - "SHA-256", - "SHA3-256", - "BLAKE-256", - "ECOH-256", - "FSB-256", - "GOST", - "Grøstl-256", - "HAVAL-256", - "PANAMA", - "RIPEMD-256", - "Snefru", - ]; - break; - case 320: - possibleHashFunctions = [ - "RIPEMD-320", - ]; - break; - case 384: - possibleHashFunctions = [ - "SHA-384", - "SHA3-384", - "ECOH-384", - "FSB-384", - ]; - break; - case 512: - possibleHashFunctions = [ - "SHA-512", - "SHA3-512", - "BLAKE-512", - "ECOH-512", - "FSB-512", - "Grøstl-512", - "JH", - "MD6", - "Spectral Hash", - "SWIFFT", - "Whirlpool", - ]; - break; - case 1024: - possibleHashFunctions = [ - "Fowler-Noll-Vo", - ]; - break; - default: - possibleHashFunctions = [ - "Unknown" - ]; - break; - } - - return output + possibleHashFunctions.join("\n"); - }, - -}; - -export default Hash; diff --git a/src/core/operations/legacy/Hexdump.js b/src/core/operations/legacy/Hexdump.js deleted file mode 100755 index 2626217a..00000000 --- a/src/core/operations/legacy/Hexdump.js +++ /dev/null @@ -1,203 +0,0 @@ -import Utils from "../Utils.js"; -import {fromHex} from "../lib/Hex"; - - -/** - * Hexdump operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Hexdump = { - - /** - * @constant - * @default - */ - WIDTH: 16, - /** - * @constant - * @default - */ - UPPER_CASE: false, - /** - * @constant - * @default - */ - INCLUDE_FINAL_LENGTH: false, - - /** - * To Hexdump operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {string} - */ - runTo: function(input, args) { - const data = new Uint8Array(input); - const length = args[0] || Hexdump.WIDTH; - const upperCase = args[1]; - const includeFinalLength = args[2]; - - let output = "", padding = 2; - for (let i = 0; i < data.length; i += length) { - const buff = data.slice(i, i+length); - let hexa = ""; - for (let j = 0; j < buff.length; j++) { - hexa += Utils.hex(buff[j], padding) + " "; - } - - let lineNo = Utils.hex(i, 8); - - if (upperCase) { - hexa = hexa.toUpperCase(); - lineNo = lineNo.toUpperCase(); - } - - output += lineNo + " " + - hexa.padEnd(length*(padding+1), " ") + - " |" + Utils.printable(Utils.byteArrayToChars(buff)).padEnd(buff.length, " ") + "|\n"; - - if (includeFinalLength && i+buff.length === data.length) { - output += Utils.hex(i+buff.length, 8) + "\n"; - } - } - - return output.slice(0, -1); - }, - - - /** - * From Hexdump operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {byteArray} - */ - runFrom: function(input, args) { - let output = [], - regex = /^\s*(?:[\dA-F]{4,16}h?:?)?\s*((?:[\dA-F]{2}\s){1,8}(?:\s|[\dA-F]{2}-)(?:[\dA-F]{2}\s){1,8}|(?:[\dA-F]{2}\s|[\dA-F]{4}\s)+)/igm, - block, line; - - while ((block = regex.exec(input))) { - line = fromHex(block[1].replace(/-/g, " ")); - for (let i = 0; i < line.length; i++) { - output.push(line[i]); - } - } - // Is this a CyberChef hexdump or is it from a different tool? - const width = input.indexOf("\n"); - const w = (width - 13) / 4; - // w should be the specified width of the hexdump and therefore a round number - if (Math.floor(w) !== w || input.indexOf("\r") !== -1 || output.indexOf(13) !== -1) { - if (ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false); - } - return output; - }, - - - /** - * Highlight to hexdump - * - * @param {Object[]} pos - * @param {number} pos[].start - * @param {number} pos[].end - * @param {Object[]} args - * @returns {Object[]} pos - */ - highlightTo: function(pos, args) { - // Calculate overall selection - let w = args[0] || 16, - width = 14 + (w*4), - line = Math.floor(pos[0].start / w), - offset = pos[0].start % w, - start = 0, - end = 0; - - pos[0].start = line*width + 10 + offset*3; - - line = Math.floor(pos[0].end / w); - offset = pos[0].end % w; - if (offset === 0) { - line--; - offset = w; - } - pos[0].end = line*width + 10 + offset*3 - 1; - - // Set up multiple selections for bytes - let startLineNum = Math.floor(pos[0].start / width); - const endLineNum = Math.floor(pos[0].end / width); - - if (startLineNum === endLineNum) { - pos.push(pos[0]); - } else { - start = pos[0].start; - end = (startLineNum+1) * width - w - 5; - pos.push({ start: start, end: end }); - while (end < pos[0].end) { - startLineNum++; - start = startLineNum * width + 10; - end = (startLineNum+1) * width - w - 5; - if (end > pos[0].end) end = pos[0].end; - pos.push({ start: start, end: end }); - } - } - - // Set up multiple selections for ASCII - let len = pos.length, lineNum = 0; - start = 0; - end = 0; - for (let i = 1; i < len; i++) { - lineNum = Math.floor(pos[i].start / width); - start = (((pos[i].start - (lineNum * width)) - 10) / 3) + (width - w -2) + (lineNum * width); - end = (((pos[i].end + 1 - (lineNum * width)) - 10) / 3) + (width - w -2) + (lineNum * width); - pos.push({ start: start, end: end }); - } - return pos; - }, - - - /** - * Highlight from hexdump - * - * @param {Object[]} pos - * @param {number} pos[].start - * @param {number} pos[].end - * @param {Object[]} args - * @returns {Object[]} pos - */ - highlightFrom: function(pos, args) { - const w = args[0] || 16; - const width = 14 + (w*4); - - let line = Math.floor(pos[0].start / width); - let offset = pos[0].start % width; - - if (offset < 10) { // In line number section - pos[0].start = line*w; - } else if (offset > 10+(w*3)) { // In ASCII section - pos[0].start = (line+1)*w; - } else { // In byte section - pos[0].start = line*w + Math.floor((offset-10)/3); - } - - line = Math.floor(pos[0].end / width); - offset = pos[0].end % width; - - if (offset < 10) { // In line number section - pos[0].end = line*w; - } else if (offset > 10+(w*3)) { // In ASCII section - pos[0].end = (line+1)*w; - } else { // In byte section - pos[0].end = line*w + Math.ceil((offset-10)/3); - } - - return pos; - }, - -}; - -export default Hexdump; diff --git a/src/core/operations/legacy/IP.js b/src/core/operations/legacy/IP.js deleted file mode 100755 index c4c3c18f..00000000 --- a/src/core/operations/legacy/IP.js +++ /dev/null @@ -1,1086 +0,0 @@ -import Utils from "../Utils.js"; -import {toHex, fromHex} from "../lib/Hex"; -import Checksum from "./Checksum.js"; -import {BigInteger} from "jsbn"; - - -/** - * Internet Protocol address operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const IP = { - - /** - * @constant - * @default - */ - INCLUDE_NETWORK_INFO: true, - /** - * @constant - * @default - */ - ENUMERATE_ADDRESSES: true, - /** - * @constant - * @default - */ - ALLOW_LARGE_LIST: false, - - /** - * Parse IP range operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runParseIpRange: function (input, args) { - let includeNetworkInfo = args[0], - enumerateAddresses = args[1], - allowLargeList = args[2]; - - // Check what type of input we are looking at - let ipv4CidrRegex = /^\s*((?:\d{1,3}\.){3}\d{1,3})\/(\d\d?)\s*$/, - ipv4RangeRegex = /^\s*((?:\d{1,3}\.){3}\d{1,3})\s*-\s*((?:\d{1,3}\.){3}\d{1,3})\s*$/, - ipv6CidrRegex = /^\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\/(\d\d?\d?)\s*$/i, - ipv6RangeRegex = /^\s*(((?=.*::)(?!.*::[^-]+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*-\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\17)::|:\b|(?![\dA-F])))|(?!\16\17)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*$/i, - match; - - if ((match = ipv4CidrRegex.exec(input))) { - return IP._ipv4CidrRange(match, includeNetworkInfo, enumerateAddresses, allowLargeList); - } else if ((match = ipv4RangeRegex.exec(input))) { - return IP._ipv4HyphenatedRange(match, includeNetworkInfo, enumerateAddresses, allowLargeList); - } else if ((match = ipv6CidrRegex.exec(input))) { - return IP._ipv6CidrRange(match, includeNetworkInfo); - } else if ((match = ipv6RangeRegex.exec(input))) { - return IP._ipv6HyphenatedRange(match, includeNetworkInfo); - } else { - return "Invalid input.\n\nEnter either a CIDR range (e.g. 10.0.0.0/24) or a hyphenated range (e.g. 10.0.0.0 - 10.0.1.0). IPv6 also supported."; - } - }, - - - /** - * @constant - * @default - */ - IPV4_REGEX: /^\s*((?:\d{1,3}\.){3}\d{1,3})\s*$/, - /** - * @constant - * @default - */ - IPV6_REGEX: /^\s*(((?=.*::)(?!.*::.+::)(::)?([\dA-F]{1,4}:(:|\b)|){5}|([\dA-F]{1,4}:){6})((([\dA-F]{1,4}((?!\4)::|:\b|(?![\dA-F])))|(?!\3\4)){2}|(((2[0-4]|1\d|[1-9])?\d|25[0-5])\.?\b){4}))\s*$/i, - - /** - * Parse IPv6 address operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runParseIPv6: function (input, args) { - let match, - output = ""; - - if ((match = IP.IPV6_REGEX.exec(input))) { - let ipv6 = IP._strToIpv6(match[1]), - longhand = IP._ipv6ToStr(ipv6), - shorthand = IP._ipv6ToStr(ipv6, true); - - output += "Longhand: " + longhand + "\nShorthand: " + shorthand + "\n"; - - // Detect reserved addresses - if (shorthand === "::") { - // Unspecified address - output += "\nUnspecified address corresponding to 0.0.0.0/32 in IPv4."; - output += "\nUnspecified address range: ::/128"; - } else if (shorthand === "::1") { - // Loopback address - output += "\nLoopback address to the local host corresponding to 127.0.0.1/8 in IPv4."; - output += "\nLoopback addresses range: ::1/128"; - } else if (ipv6[0] === 0 && ipv6[1] === 0 && ipv6[2] === 0 && - ipv6[3] === 0 && ipv6[4] === 0 && ipv6[5] === 0xffff) { - // IPv4-mapped IPv6 address - output += "\nIPv4-mapped IPv6 address detected. IPv6 clients will be handled natively by default, and IPv4 clients appear as IPv6 clients at their IPv4-mapped IPv6 address."; - output += "\nMapped IPv4 address: " + IP._ipv4ToStr((ipv6[6] << 16) + ipv6[7]); - output += "\nIPv4-mapped IPv6 addresses range: ::ffff:0:0/96"; - } else if (ipv6[0] === 0 && ipv6[1] === 0 && ipv6[2] === 0 && - ipv6[3] === 0 && ipv6[4] === 0xffff && ipv6[5] === 0) { - // IPv4-translated address - output += "\nIPv4-translated address detected. Used by Stateless IP/ICMP Translation (SIIT). See RFCs 6145 and 6052 for more details."; - output += "\nTranslated IPv4 address: " + IP._ipv4ToStr((ipv6[6] << 16) + ipv6[7]); - output += "\nIPv4-translated addresses range: ::ffff:0:0:0/96"; - } else if (ipv6[0] === 0x100) { - // Discard prefix per RFC 6666 - output += "\nDiscard prefix detected. This is used when forwarding traffic to a sinkhole router to mitigate the effects of a denial-of-service attack. See RFC 6666 for more details."; - output += "\nDiscard range: 100::/64"; - } else if (ipv6[0] === 0x64 && ipv6[1] === 0xff9b && ipv6[2] === 0 && - ipv6[3] === 0 && ipv6[4] === 0 && ipv6[5] === 0) { - // IPv4/IPv6 translation per RFC 6052 - output += "\n'Well-Known' prefix for IPv4/IPv6 translation detected. See RFC 6052 for more details."; - output += "\nTranslated IPv4 address: " + IP._ipv4ToStr((ipv6[6] << 16) + ipv6[7]); - output += "\n'Well-Known' prefix range: 64:ff9b::/96"; - } else if (ipv6[0] === 0x2001 && ipv6[1] === 0) { - // Teredo tunneling - output += "\nTeredo tunneling IPv6 address detected\n"; - let serverIpv4 = (ipv6[2] << 16) + ipv6[3], - udpPort = (~ipv6[5]) & 0xffff, - clientIpv4 = ~((ipv6[6] << 16) + ipv6[7]), - flagCone = (ipv6[4] >>> 15) & 1, - flagR = (ipv6[4] >>> 14) & 1, - flagRandom1 = (ipv6[4] >>> 10) & 15, - flagUg = (ipv6[4] >>> 8) & 3, - flagRandom2 = ipv6[4] & 255; - - output += "\nServer IPv4 address: " + IP._ipv4ToStr(serverIpv4) + - "\nClient IPv4 address: " + IP._ipv4ToStr(clientIpv4) + - "\nClient UDP port: " + udpPort + - "\nFlags:" + - "\n\tCone: " + flagCone; - - if (flagCone) { - output += " (Client is behind a cone NAT)"; - } else { - output += " (Client is not behind a cone NAT)"; - } - - output += "\n\tR: " + flagR; - - if (flagR) { - output += " Error: This flag should be set to 0. See RFC 5991 and RFC 4380."; - } - - output += "\n\tRandom1: " + Utils.bin(flagRandom1, 4) + - "\n\tUG: " + Utils.bin(flagUg, 2); - - if (flagUg) { - output += " Error: This flag should be set to 00. See RFC 4380."; - } - - output += "\n\tRandom2: " + Utils.bin(flagRandom2, 8); - - if (!flagR && !flagUg && flagRandom1 && flagRandom2) { - output += "\n\nThis is a valid Teredo address which complies with RFC 4380 and RFC 5991."; - } else if (!flagR && !flagUg) { - output += "\n\nThis is a valid Teredo address which complies with RFC 4380, however it does not comply with RFC 5991 (Teredo Security Updates) as there are no randomised bits in the flag field."; - } else { - output += "\n\nThis is an invalid Teredo address."; - } - output += "\n\nTeredo prefix range: 2001::/32"; - } else if (ipv6[0] === 0x2001 && ipv6[1] === 0x2 && ipv6[2] === 0) { - // Benchmarking - output += "\nAssigned to the Benchmarking Methodology Working Group (BMWG) for benchmarking IPv6. Corresponds to 198.18.0.0/15 for benchmarking IPv4. See RFC 5180 for more details."; - output += "\nBMWG range: 2001:2::/48"; - } else if (ipv6[0] === 0x2001 && ipv6[1] >= 0x10 && ipv6[1] <= 0x1f) { - // ORCHIDv1 - output += "\nDeprecated, previously ORCHIDv1 (Overlay Routable Cryptographic Hash Identifiers).\nORCHIDv1 range: 2001:10::/28\nORCHIDv2 now uses 2001:20::/28."; - } else if (ipv6[0] === 0x2001 && ipv6[1] >= 0x20 && ipv6[1] <= 0x2f) { - // ORCHIDv2 - output += "\nORCHIDv2 (Overlay Routable Cryptographic Hash Identifiers).\nThese are non-routed IPv6 addresses used for Cryptographic Hash Identifiers."; - output += "\nORCHIDv2 range: 2001:20::/28"; - } else if (ipv6[0] === 0x2001 && ipv6[1] === 0xdb8) { - // Documentation - output += "\nThis is a documentation IPv6 address. This range should be used whenever an example IPv6 address is given or to model networking scenarios. Corresponds to 192.0.2.0/24, 198.51.100.0/24, and 203.0.113.0/24 in IPv4."; - output += "\nDocumentation range: 2001:db8::/32"; - } else if (ipv6[0] === 0x2002) { - // 6to4 - output += "\n6to4 transition IPv6 address detected. See RFC 3056 for more details." + - "\n6to4 prefix range: 2002::/16"; - - let v4Addr = IP._ipv4ToStr((ipv6[1] << 16) + ipv6[2]), - slaId = ipv6[3], - interfaceIdStr = ipv6[4].toString(16) + ipv6[5].toString(16) + ipv6[6].toString(16) + ipv6[7].toString(16), - interfaceId = new BigInteger(interfaceIdStr, 16); - - output += "\n\nEncapsulated IPv4 address: " + v4Addr + - "\nSLA ID: " + slaId + - "\nInterface ID (base 16): " + interfaceIdStr + - "\nInterface ID (base 10): " + interfaceId.toString(); - } else if (ipv6[0] >= 0xfc00 && ipv6[0] <= 0xfdff) { - // Unique local address - output += "\nThis is a unique local address comparable to the IPv4 private addresses 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16. See RFC 4193 for more details."; - output += "\nUnique local addresses range: fc00::/7"; - } else if (ipv6[0] >= 0xfe80 && ipv6[0] <= 0xfebf) { - // Link-local address - output += "\nThis is a link-local address comparable to the auto-configuration addresses 169.254.0.0/16 in IPv4."; - output += "\nLink-local addresses range: fe80::/10"; - } else if (ipv6[0] >= 0xff00) { - // Multicast - output += "\nThis is a reserved multicast address."; - output += "\nMulticast addresses range: ff00::/8"; - } - - - // Detect possible EUI-64 addresses - if ((ipv6[5] & 0xff === 0xff) && (ipv6[6] >>> 8 === 0xfe)) { - output += "\n\nThis IPv6 address contains a modified EUI-64 address, identified by the presence of FF:FE in the 12th and 13th octets."; - - let intIdent = Utils.hex(ipv6[4] >>> 8) + ":" + Utils.hex(ipv6[4] & 0xff) + ":" + - Utils.hex(ipv6[5] >>> 8) + ":" + Utils.hex(ipv6[5] & 0xff) + ":" + - Utils.hex(ipv6[6] >>> 8) + ":" + Utils.hex(ipv6[6] & 0xff) + ":" + - Utils.hex(ipv6[7] >>> 8) + ":" + Utils.hex(ipv6[7] & 0xff), - mac = Utils.hex((ipv6[4] >>> 8) ^ 2) + ":" + Utils.hex(ipv6[4] & 0xff) + ":" + - Utils.hex(ipv6[5] >>> 8) + ":" + Utils.hex(ipv6[6] & 0xff) + ":" + - Utils.hex(ipv6[7] >>> 8) + ":" + Utils.hex(ipv6[7] & 0xff); - output += "\nInterface identifier: " + intIdent + - "\nMAC address: " + mac; - } - } else { - return "Invalid IPv6 address"; - } - return output; - }, - - - /** - * @constant - * @default - */ - IP_FORMAT_LIST: ["Dotted Decimal", "Decimal", "Hex"], - - /** - * Change IP format operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runChangeIpFormat: function(input, args) { - let inFormat = args[0], - outFormat = args[1], - lines = input.split("\n"), - output = "", - j = 0; - - - for (let i = 0; i < lines.length; i++) { - if (lines[i] === "") continue; - let baIp = []; - let octets; - let decimal; - - if (inFormat === outFormat) { - output += lines[i] + "\n"; - continue; - } - - // Convert to byte array IP from input format - switch (inFormat) { - case "Dotted Decimal": - octets = lines[i].split("."); - for (j = 0; j < octets.length; j++) { - baIp.push(parseInt(octets[j], 10)); - } - break; - case "Decimal": - decimal = lines[i].toString(); - baIp.push(decimal >> 24 & 255); - baIp.push(decimal >> 16 & 255); - baIp.push(decimal >> 8 & 255); - baIp.push(decimal & 255); - break; - case "Hex": - baIp = fromHex(lines[i]); - break; - default: - throw "Unsupported input IP format"; - } - - let ddIp; - let decIp; - let hexIp; - - // Convert byte array IP to output format - switch (outFormat) { - case "Dotted Decimal": - ddIp = ""; - for (j = 0; j < baIp.length; j++) { - ddIp += baIp[j] + "."; - } - output += ddIp.slice(0, ddIp.length-1) + "\n"; - break; - case "Decimal": - decIp = ((baIp[0] << 24) | (baIp[1] << 16) | (baIp[2] << 8) | baIp[3]) >>> 0; - output += decIp.toString() + "\n"; - break; - case "Hex": - hexIp = ""; - for (j = 0; j < baIp.length; j++) { - hexIp += Utils.hex(baIp[j]); - } - output += hexIp + "\n"; - break; - default: - throw "Unsupported output IP format"; - } - } - - return output.slice(0, output.length-1); - }, - - - /** - * @constant - * @default - */ - DELIM_OPTIONS: ["Line feed", "CRLF", "Space", "Comma", "Semi-colon"], - /** - * @constant - * @default - */ - GROUP_CIDR: 24, - /** - * @constant - * @default - */ - GROUP_ONLY_SUBNET: false, - - /** - * Group IP addresses operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runGroupIps: function(input, args) { - let delim = Utils.charRep(args[0]), - cidr = args[1], - onlySubnets = args[2], - ipv4Mask = cidr < 32 ? ~(0xFFFFFFFF >>> cidr) : 0xFFFFFFFF, - ipv6Mask = IP._genIpv6Mask(cidr), - ips = input.split(delim), - ipv4Networks = {}, - ipv6Networks = {}, - match = null, - output = "", - ip = null, - network = null, - networkStr = "", - i; - - if (cidr < 0 || cidr > 127) { - return "CIDR must be less than 32 for IPv4 or 128 for IPv6"; - } - - // Parse all IPs and add to network dictionary - for (i = 0; i < ips.length; i++) { - if ((match = IP.IPV4_REGEX.exec(ips[i]))) { - ip = IP._strToIpv4(match[1]) >>> 0; - network = ip & ipv4Mask; - - if (ipv4Networks.hasOwnProperty(network)) { - ipv4Networks[network].push(ip); - } else { - ipv4Networks[network] = [ip]; - } - } else if ((match = IP.IPV6_REGEX.exec(ips[i]))) { - ip = IP._strToIpv6(match[1]); - network = []; - networkStr = ""; - - for (let j = 0; j < 8; j++) { - network.push(ip[j] & ipv6Mask[j]); - } - - networkStr = IP._ipv6ToStr(network, true); - - if (ipv6Networks.hasOwnProperty(networkStr)) { - ipv6Networks[networkStr].push(ip); - } else { - ipv6Networks[networkStr] = [ip]; - } - } - } - - // Sort IPv4 network dictionaries and print - for (network in ipv4Networks) { - ipv4Networks[network] = ipv4Networks[network].sort(); - - output += IP._ipv4ToStr(network) + "/" + cidr + "\n"; - - if (!onlySubnets) { - for (i = 0; i < ipv4Networks[network].length; i++) { - output += " " + IP._ipv4ToStr(ipv4Networks[network][i]) + "\n"; - } - output += "\n"; - } - } - - // Sort IPv6 network dictionaries and print - for (networkStr in ipv6Networks) { - //ipv6Networks[networkStr] = ipv6Networks[networkStr].sort(); TODO - - output += networkStr + "/" + cidr + "\n"; - - if (!onlySubnets) { - for (i = 0; i < ipv6Networks[networkStr].length; i++) { - output += " " + IP._ipv6ToStr(ipv6Networks[networkStr][i], true) + "\n"; - } - output += "\n"; - } - } - - return output; - }, - - - /** - * @constant - * @default - */ - IP_HEADER_FORMAT: ["Hex", "Raw"], - - /** - * Parse IPv4 header operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {html} - */ - runParseIPv4Header: function(input, args) { - let format = args[0], - output; - - if (format === "Hex") { - input = fromHex(input); - } else if (format === "Raw") { - input = Utils.strToByteArray(input); - } else { - return "Unrecognised input format."; - } - - let version = (input[0] >>> 4) & 0x0f, - ihl = input[0] & 0x0f, - dscp = (input[1] >>> 2) & 0x3f, - ecn = input[1] & 0x03, - length = input[2] << 8 | input[3], - identification = input[4] << 8 | input[5], - flags = (input[6] >>> 5) & 0x07, - fragOffset = (input[6] & 0x1f) << 8 | input[7], - ttl = input[8], - protocol = input[9], - checksum = input[10] << 8 | input[11], - srcIP = input[12] << 24 | input[13] << 16 | input[14] << 8 | input[15], - dstIP = input[16] << 24 | input[17] << 16 | input[18] << 8 | input[19], - checksumHeader = input.slice(0, 10).concat([0, 0]).concat(input.slice(12, 20)), - options = []; - - // Version - if (version !== 4) { - version = version + " (Error: for IPv4 headers, this should always be set to 4)"; - } - - // IHL - if (ihl < 5) { - ihl = ihl + " (Error: this should always be at least 5)"; - } else if (ihl > 5) { - // sort out options... - const optionsLen = ihl * 4 - 20; - options = input.slice(20, optionsLen + 20); - } - - // Protocol - const protocolInfo = IP._protocolLookup[protocol] || {keyword: "", protocol: ""}; - - // Checksum - let correctChecksum = Checksum.runTCPIP(checksumHeader, []), - givenChecksum = Utils.hex(checksum), - checksumResult; - if (correctChecksum === givenChecksum) { - checksumResult = givenChecksum + " (correct)"; - } else { - checksumResult = givenChecksum + " (incorrect, should be " + correctChecksum + ")"; - } - - output = "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - "" + - ""; - - if (ihl > 5) { - output += ""; - } - - return output + "
FieldValue
Version" + version + "
Internet Header Length (IHL)" + ihl + " (" + (ihl * 4) + " bytes)
Differentiated Services Code Point (DSCP)" + dscp + "
Explicit Congestion Notification (ECN)" + ecn + "
Total length" + length + " bytes" + - "\n IP header: " + (ihl * 4) + " bytes" + - "\n Data: " + (length - ihl * 4) + " bytes
Identification0x" + Utils.hex(identification) + " (" + identification + ")
Flags0x" + Utils.hex(flags, 2) + - "\n Reserved bit:" + (flags >> 2) + " (must be 0)" + - "\n Don't fragment:" + (flags >> 1 & 1) + - "\n More fragments:" + (flags & 1) + "
Fragment offset" + fragOffset + "
Time-To-Live" + ttl + "
Protocol" + protocol + ", " + protocolInfo.protocol + " (" + protocolInfo.keyword + ")
Header checksum" + checksumResult + "
Source IP address" + IP._ipv4ToStr(srcIP) + "
Destination IP address" + IP._ipv4ToStr(dstIP) + "
Options" + toHex(options) + "
"; - }, - - - /** - * @constant - * @default - * @private - */ - _LARGE_RANGE_ERROR: "The specified range contains more than 65,536 addresses. Running this query could crash your browser. If you want to run it, select the \"Allow large queries\" option. You are advised to turn off \"Auto Bake\" whilst editing large ranges.", - - /** - * Parses an IPv4 CIDR range (e.g. 192.168.0.0/24) and displays information about it. - * - * @private - * @param {RegExp} cidr - * @param {boolean} includeNetworkInfo - * @param {boolean} enumerateAddresses - * @param {boolean} allowLargeList - * @returns {string} - */ - _ipv4CidrRange: function(cidr, includeNetworkInfo, enumerateAddresses, allowLargeList) { - let output = "", - network = IP._strToIpv4(cidr[1]), - cidrRange = parseInt(cidr[2], 10); - - if (cidrRange < 0 || cidrRange > 31) { - return "IPv4 CIDR must be less than 32"; - } - - let mask = ~(0xFFFFFFFF >>> cidrRange), - ip1 = network & mask, - ip2 = ip1 | ~mask; - - if (includeNetworkInfo) { - output += "Network: " + IP._ipv4ToStr(network) + "\n"; - output += "CIDR: " + cidrRange + "\n"; - output += "Mask: " + IP._ipv4ToStr(mask) + "\n"; - output += "Range: " + IP._ipv4ToStr(ip1) + " - " + IP._ipv4ToStr(ip2) + "\n"; - output += "Total addresses in range: " + (((ip2 - ip1) >>> 0) + 1) + "\n\n"; - } - - if (enumerateAddresses) { - if (cidrRange >= 16 || allowLargeList) { - output += IP._generateIpv4Range(ip1, ip2).join("\n"); - } else { - output += IP._LARGE_RANGE_ERROR; - } - } - return output; - }, - - - /** - * Parses an IPv6 CIDR range (e.g. ff00::/48) and displays information about it. - * - * @private - * @param {RegExp} cidr - * @param {boolean} includeNetworkInfo - * @returns {string} - */ - _ipv6CidrRange: function(cidr, includeNetworkInfo) { - let output = "", - network = IP._strToIpv6(cidr[1]), - cidrRange = parseInt(cidr[cidr.length-1], 10); - - if (cidrRange < 0 || cidrRange > 127) { - return "IPv6 CIDR must be less than 128"; - } - - let mask = IP._genIpv6Mask(cidrRange), - ip1 = new Array(8), - ip2 = new Array(8), - totalDiff = "", - total = new Array(128); - - for (let i = 0; i < 8; i++) { - ip1[i] = network[i] & mask[i]; - ip2[i] = ip1[i] | (~mask[i] & 0x0000FFFF); - totalDiff = (ip2[i] - ip1[i]).toString(2); - - if (totalDiff !== "0") { - for (let n = 0; n < totalDiff.length; n++) { - total[i*16 + 16-(totalDiff.length-n)] = totalDiff[n]; - } - } - } - - if (includeNetworkInfo) { - output += "Network: " + IP._ipv6ToStr(network) + "\n"; - output += "Shorthand: " + IP._ipv6ToStr(network, true) + "\n"; - output += "CIDR: " + cidrRange + "\n"; - output += "Mask: " + IP._ipv6ToStr(mask) + "\n"; - output += "Range: " + IP._ipv6ToStr(ip1) + " - " + IP._ipv6ToStr(ip2) + "\n"; - output += "Total addresses in range: " + (parseInt(total.join(""), 2) + 1) + "\n\n"; - } - - return output; - }, - - - /** - * Generates an IPv6 subnet mask given a CIDR value. - * - * @private - * @param {number} cidr - * @returns {number[]} - */ - _genIpv6Mask: function(cidr) { - let mask = new Array(8), - shift; - - for (let i = 0; i < 8; i++) { - if (cidr > ((i+1)*16)) { - mask[i] = 0x0000FFFF; - } else { - shift = cidr-(i*16); - if (shift < 0) shift = 0; - mask[i] = ~((0x0000FFFF >>> shift) | 0xFFFF0000); - } - } - - return mask; - }, - - - /** - * Parses an IPv4 hyphenated range (e.g. 192.168.0.0 - 192.168.0.255) and displays information - * about it. - * - * @private - * @param {RegExp} range - * @param {boolean} includeNetworkInfo - * @param {boolean} enumerateAddresses - * @param {boolean} allowLargeList - * @returns {string} - */ - _ipv4HyphenatedRange: function(range, includeNetworkInfo, enumerateAddresses, allowLargeList) { - let output = "", - ip1 = IP._strToIpv4(range[1]), - ip2 = IP._strToIpv4(range[2]); - - // Calculate mask - let diff = ip1 ^ ip2, - cidr = 32, - mask = 0; - - while (diff !== 0) { - diff >>= 1; - cidr--; - mask = (mask << 1) | 1; - } - - mask = ~mask >>> 0; - let network = ip1 & mask, - subIp1 = network & mask, - subIp2 = subIp1 | ~mask; - - if (includeNetworkInfo) { - output += "Minimum subnet required to hold this range:\n"; - output += "\tNetwork: " + IP._ipv4ToStr(network) + "\n"; - output += "\tCIDR: " + cidr + "\n"; - output += "\tMask: " + IP._ipv4ToStr(mask) + "\n"; - output += "\tSubnet range: " + IP._ipv4ToStr(subIp1) + " - " + IP._ipv4ToStr(subIp2) + "\n"; - output += "\tTotal addresses in subnet: " + (((subIp2 - subIp1) >>> 0) + 1) + "\n\n"; - output += "Range: " + IP._ipv4ToStr(ip1) + " - " + IP._ipv4ToStr(ip2) + "\n"; - output += "Total addresses in range: " + (((ip2 - ip1) >>> 0) + 1) + "\n\n"; - } - - if (enumerateAddresses) { - if (((ip2 - ip1) >>> 0) <= 65536 || allowLargeList) { - output += IP._generateIpv4Range(ip1, ip2).join("\n"); - } else { - output += IP._LARGE_RANGE_ERROR; - } - } - return output; - }, - - - /** - * Parses an IPv6 hyphenated range (e.g. ff00:: - ffff::) and displays information about it. - * - * @private - * @param {RegExp} range - * @param {boolean} includeNetworkInfo - * @returns {string} - */ - _ipv6HyphenatedRange: function(range, includeNetworkInfo) { - let output = "", - ip1 = IP._strToIpv6(range[1]), - ip2 = IP._strToIpv6(range[14]); - - let t = "", - total = new Array(128).fill(), - i; - - for (i = 0; i < 8; i++) { - t = (ip2[i] - ip1[i]).toString(2); - if (t !== "0") { - for (let n = 0; n < t.length; n++) { - total[i*16 + 16-(t.length-n)] = t[n]; - } - } - } - - if (includeNetworkInfo) { - output += "Range: " + IP._ipv6ToStr(ip1) + " - " + IP._ipv6ToStr(ip2) + "\n"; - output += "Shorthand range: " + IP._ipv6ToStr(ip1, true) + " - " + IP._ipv6ToStr(ip2, true) + "\n"; - output += "Total addresses in range: " + (parseInt(total.join(""), 2) + 1) + "\n\n"; - } - - return output; - }, - - - /** - * Converts an IPv4 address from string format to numerical format. - * - * @private - * @param {string} ipStr - * @returns {number} - * - * @example - * // returns 168427520 - * IP._strToIpv4("10.10.0.0"); - */ - _strToIpv4: function (ipStr) { - let blocks = ipStr.split("."), - numBlocks = parseBlocks(blocks), - result = 0; - - result += numBlocks[0] << 24; - result += numBlocks[1] << 16; - result += numBlocks[2] << 8; - result += numBlocks[3]; - - return result; - - /** - * Converts a list of 4 numeric strings in the range 0-255 to a list of numbers. - */ - function parseBlocks(blocks) { - if (blocks.length !== 4) - throw "More than 4 blocks."; - - const numBlocks = []; - for (let i = 0; i < 4; i++) { - numBlocks[i] = parseInt(blocks[i], 10); - if (numBlocks[i] < 0 || numBlocks[i] > 255) - throw "Block out of range."; - } - return numBlocks; - } - }, - - - /** - * Converts an IPv4 address from numerical format to string format. - * - * @private - * @param {number} ipInt - * @returns {string} - * - * @example - * // returns "10.10.0.0" - * IP._ipv4ToStr(168427520); - */ - _ipv4ToStr: function(ipInt) { - let blockA = (ipInt >> 24) & 255, - blockB = (ipInt >> 16) & 255, - blockC = (ipInt >> 8) & 255, - blockD = ipInt & 255; - - return blockA + "." + blockB + "." + blockC + "." + blockD; - }, - - - /** - * Converts an IPv6 address from string format to numerical array format. - * - * @private - * @param {string} ipStr - * @returns {number[]} - * - * @example - * // returns [65280, 0, 0, 0, 0, 0, 4369, 8738] - * IP._strToIpv6("ff00::1111:2222"); - */ - _strToIpv6: function(ipStr) { - let blocks = ipStr.split(":"), - numBlocks = parseBlocks(blocks), - j = 0, - ipv6 = new Array(8); - - for (let i = 0; i < 8; i++) { - if (isNaN(numBlocks[j])) { - ipv6[i] = 0; - if (i === (8-numBlocks.slice(j).length)) j++; - } else { - ipv6[i] = numBlocks[j]; - j++; - } - } - return ipv6; - - /** - * Converts a list of 3-8 numeric hex strings in the range 0-65535 to a list of numbers. - */ - function parseBlocks(blocks) { - if (blocks.length < 3 || blocks.length > 8) - throw "Badly formatted IPv6 address."; - const numBlocks = []; - for (let i = 0; i < blocks.length; i++) { - numBlocks[i] = parseInt(blocks[i], 16); - if (numBlocks[i] < 0 || numBlocks[i] > 65535) - throw "Block out of range."; - } - return numBlocks; - } - }, - - - /** - * Converts an IPv6 address from numerical array format to string format. - * - * @private - * @param {number[]} ipv6 - * @param {boolean} compact - Whether or not to return the address in shorthand or not - * @returns {string} - * - * @example - * // returns "ff00::1111:2222" - * IP._ipv6ToStr([65280, 0, 0, 0, 0, 0, 4369, 8738], true); - * - * // returns "ff00:0000:0000:0000:0000:0000:1111:2222" - * IP._ipv6ToStr([65280, 0, 0, 0, 0, 0, 4369, 8738], false); - */ - _ipv6ToStr: function(ipv6, compact) { - let output = "", - i = 0; - - if (compact) { - let start = -1, - end = -1, - s = 0, - e = -1; - - for (i = 0; i < 8; i++) { - if (ipv6[i] === 0 && e === (i-1)) { - e = i; - } else if (ipv6[i] === 0) { - s = i; e = i; - } - if (e >= 0 && (e-s) > (end - start)) { - start = s; - end = e; - } - } - - for (i = 0; i < 8; i++) { - if (i !== start) { - output += Utils.hex(ipv6[i], 1) + ":"; - } else { - output += ":"; - i = end; - if (end === 7) output += ":"; - } - } - if (output[0] === ":") - output = ":" + output; - } else { - for (i = 0; i < 8; i++) { - output += Utils.hex(ipv6[i], 4) + ":"; - } - } - return output.slice(0, output.length-1); - }, - - - /** - * Generates a list of IPv4 addresses in string format between two given numerical values. - * - * @private - * @param {number} ip - * @param {number} endIp - * @returns {string[]} - * - * @example - * // returns ["0.0.0.1", "0.0.0.2", "0.0.0.3"] - * IP._generateIpv4Range(1, 3); - */ - _generateIpv4Range: function(ip, endIp) { - const range = []; - if (endIp >= ip) { - for (; ip <= endIp; ip++) { - range.push(IP._ipv4ToStr(ip)); - } - } else { - range[0] = "Second IP address smaller than first."; - } - return range; - }, - - - /** - * Lookup table for Internet Protocols. - * Taken from https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml - * - * @private - * @constant - */ - _protocolLookup: { - 0: {keyword: "HOPOPT", protocol: "IPv6 Hop-by-Hop Option"}, - 1: {keyword: "ICMP", protocol: "Internet Control Message"}, - 2: {keyword: "IGMP", protocol: "Internet Group Management"}, - 3: {keyword: "GGP", protocol: "Gateway-to-Gateway"}, - 4: {keyword: "IPv4", protocol: "IPv4 encapsulation"}, - 5: {keyword: "ST", protocol: "Stream"}, - 6: {keyword: "TCP", protocol: "Transmission Control"}, - 7: {keyword: "CBT", protocol: "CBT"}, - 8: {keyword: "EGP", protocol: "Exterior Gateway Protocol"}, - 9: {keyword: "IGP", protocol: "any private interior gateway (used by Cisco for their IGRP)"}, - 10: {keyword: "BBN-RCC-MON", protocol: "BBN RCC Monitoring"}, - 11: {keyword: "NVP-II", protocol: "Network Voice Protocol"}, - 12: {keyword: "PUP", protocol: "PUP"}, - 13: {keyword: "ARGUS (deprecated)", protocol: "ARGUS"}, - 14: {keyword: "EMCON", protocol: "EMCON"}, - 15: {keyword: "XNET", protocol: "Cross Net Debugger"}, - 16: {keyword: "CHAOS", protocol: "Chaos"}, - 17: {keyword: "UDP", protocol: "User Datagram"}, - 18: {keyword: "MUX", protocol: "Multiplexing"}, - 19: {keyword: "DCN-MEAS", protocol: "DCN Measurement Subsystems"}, - 20: {keyword: "HMP", protocol: "Host Monitoring"}, - 21: {keyword: "PRM", protocol: "Packet Radio Measurement"}, - 22: {keyword: "XNS-IDP", protocol: "XEROX NS IDP"}, - 23: {keyword: "TRUNK-1", protocol: "Trunk-1"}, - 24: {keyword: "TRUNK-2", protocol: "Trunk-2"}, - 25: {keyword: "LEAF-1", protocol: "Leaf-1"}, - 26: {keyword: "LEAF-2", protocol: "Leaf-2"}, - 27: {keyword: "RDP", protocol: "Reliable Data Protocol"}, - 28: {keyword: "IRTP", protocol: "Internet Reliable Transaction"}, - 29: {keyword: "ISO-TP4", protocol: "ISO Transport Protocol Class 4"}, - 30: {keyword: "NETBLT", protocol: "Bulk Data Transfer Protocol"}, - 31: {keyword: "MFE-NSP", protocol: "MFE Network Services Protocol"}, - 32: {keyword: "MERIT-INP", protocol: "MERIT Internodal Protocol"}, - 33: {keyword: "DCCP", protocol: "Datagram Congestion Control Protocol"}, - 34: {keyword: "3PC", protocol: "Third Party Connect Protocol"}, - 35: {keyword: "IDPR", protocol: "Inter-Domain Policy Routing Protocol"}, - 36: {keyword: "XTP", protocol: "XTP"}, - 37: {keyword: "DDP", protocol: "Datagram Delivery Protocol"}, - 38: {keyword: "IDPR-CMTP", protocol: "IDPR Control Message Transport Proto"}, - 39: {keyword: "TP++", protocol: "TP++ Transport Protocol"}, - 40: {keyword: "IL", protocol: "IL Transport Protocol"}, - 41: {keyword: "IPv6", protocol: "IPv6 encapsulation"}, - 42: {keyword: "SDRP", protocol: "Source Demand Routing Protocol"}, - 43: {keyword: "IPv6-Route", protocol: "Routing Header for IPv6"}, - 44: {keyword: "IPv6-Frag", protocol: "Fragment Header for IPv6"}, - 45: {keyword: "IDRP", protocol: "Inter-Domain Routing Protocol"}, - 46: {keyword: "RSVP", protocol: "Reservation Protocol"}, - 47: {keyword: "GRE", protocol: "Generic Routing Encapsulation"}, - 48: {keyword: "DSR", protocol: "Dynamic Source Routing Protocol"}, - 49: {keyword: "BNA", protocol: "BNA"}, - 50: {keyword: "ESP", protocol: "Encap Security Payload"}, - 51: {keyword: "AH", protocol: "Authentication Header"}, - 52: {keyword: "I-NLSP", protocol: "Integrated Net Layer Security TUBA"}, - 53: {keyword: "SWIPE (deprecated)", protocol: "IP with Encryption"}, - 54: {keyword: "NARP", protocol: "NBMA Address Resolution Protocol"}, - 55: {keyword: "MOBILE", protocol: "IP Mobility"}, - 56: {keyword: "TLSP", protocol: "Transport Layer Security Protocol using Kryptonet key management"}, - 57: {keyword: "SKIP", protocol: "SKIP"}, - 58: {keyword: "IPv6-ICMP", protocol: "ICMP for IPv6"}, - 59: {keyword: "IPv6-NoNxt", protocol: "No Next Header for IPv6"}, - 60: {keyword: "IPv6-Opts", protocol: "Destination Options for IPv6"}, - 61: {keyword: "", protocol: "any host internal protocol"}, - 62: {keyword: "CFTP", protocol: "CFTP"}, - 63: {keyword: "", protocol: "any local network"}, - 64: {keyword: "SAT-EXPAK", protocol: "SATNET and Backroom EXPAK"}, - 65: {keyword: "KRYPTOLAN", protocol: "Kryptolan"}, - 66: {keyword: "RVD", protocol: "MIT Remote Virtual Disk Protocol"}, - 67: {keyword: "IPPC", protocol: "Internet Pluribus Packet Core"}, - 68: {keyword: "", protocol: "any distributed file system"}, - 69: {keyword: "SAT-MON", protocol: "SATNET Monitoring"}, - 70: {keyword: "VISA", protocol: "VISA Protocol"}, - 71: {keyword: "IPCV", protocol: "Internet Packet Core Utility"}, - 72: {keyword: "CPNX", protocol: "Computer Protocol Network Executive"}, - 73: {keyword: "CPHB", protocol: "Computer Protocol Heart Beat"}, - 74: {keyword: "WSN", protocol: "Wang Span Network"}, - 75: {keyword: "PVP", protocol: "Packet Video Protocol"}, - 76: {keyword: "BR-SAT-MON", protocol: "Backroom SATNET Monitoring"}, - 77: {keyword: "SUN-ND", protocol: "SUN ND PROTOCOL-Temporary"}, - 78: {keyword: "WB-MON", protocol: "WIDEBAND Monitoring"}, - 79: {keyword: "WB-EXPAK", protocol: "WIDEBAND EXPAK"}, - 80: {keyword: "ISO-IP", protocol: "ISO Internet Protocol"}, - 81: {keyword: "VMTP", protocol: "VMTP"}, - 82: {keyword: "SECURE-VMTP", protocol: "SECURE-VMTP"}, - 83: {keyword: "VINES", protocol: "VINES"}, - 84: {keyword: "TTP", protocol: "Transaction Transport Protocol"}, - 85: {keyword: "NSFNET-IGP", protocol: "NSFNET-IGP"}, - 86: {keyword: "DGP", protocol: "Dissimilar Gateway Protocol"}, - 87: {keyword: "TCF", protocol: "TCF"}, - 88: {keyword: "EIGRP", protocol: "EIGRP"}, - 89: {keyword: "OSPFIGP", protocol: "OSPFIGP"}, - 90: {keyword: "Sprite-RPC", protocol: "Sprite RPC Protocol"}, - 91: {keyword: "LARP", protocol: "Locus Address Resolution Protocol"}, - 92: {keyword: "MTP", protocol: "Multicast Transport Protocol"}, - 93: {keyword: "AX.25", protocol: "AX.25 Frames"}, - 94: {keyword: "IPIP", protocol: "IP-within-IP Encapsulation Protocol"}, - 95: {keyword: "MICP (deprecated)", protocol: "Mobile Internetworking Control Pro."}, - 96: {keyword: "SCC-SP", protocol: "Semaphore Communications Sec. Pro."}, - 97: {keyword: "ETHERIP", protocol: "Ethernet-within-IP Encapsulation"}, - 98: {keyword: "ENCAP", protocol: "Encapsulation Header"}, - 99: {keyword: "", protocol: "any private encryption scheme"}, - 100: {keyword: "GMTP", protocol: "GMTP"}, - 101: {keyword: "IFMP", protocol: "Ipsilon Flow Management Protocol"}, - 102: {keyword: "PNNI", protocol: "PNNI over IP"}, - 103: {keyword: "PIM", protocol: "Protocol Independent Multicast"}, - 104: {keyword: "ARIS", protocol: "ARIS"}, - 105: {keyword: "SCPS", protocol: "SCPS"}, - 106: {keyword: "QNX", protocol: "QNX"}, - 107: {keyword: "A/N", protocol: "Active Networks"}, - 108: {keyword: "IPComp", protocol: "IP Payload Compression Protocol"}, - 109: {keyword: "SNP", protocol: "Sitara Networks Protocol"}, - 110: {keyword: "Compaq-Peer", protocol: "Compaq Peer Protocol"}, - 111: {keyword: "IPX-in-IP", protocol: "IPX in IP"}, - 112: {keyword: "VRRP", protocol: "Virtual Router Redundancy Protocol"}, - 113: {keyword: "PGM", protocol: "PGM Reliable Transport Protocol"}, - 114: {keyword: "", protocol: "any 0-hop protocol"}, - 115: {keyword: "L2TP", protocol: "Layer Two Tunneling Protocol"}, - 116: {keyword: "DDX", protocol: "D-II Data Exchange (DDX)"}, - 117: {keyword: "IATP", protocol: "Interactive Agent Transfer Protocol"}, - 118: {keyword: "STP", protocol: "Schedule Transfer Protocol"}, - 119: {keyword: "SRP", protocol: "SpectraLink Radio Protocol"}, - 120: {keyword: "UTI", protocol: "UTI"}, - 121: {keyword: "SMP", protocol: "Simple Message Protocol"}, - 122: {keyword: "SM (deprecated)", protocol: "Simple Multicast Protocol"}, - 123: {keyword: "PTP", protocol: "Performance Transparency Protocol"}, - 124: {keyword: "ISIS over IPv4", protocol: ""}, - 125: {keyword: "FIRE", protocol: ""}, - 126: {keyword: "CRTP", protocol: "Combat Radio Transport Protocol"}, - 127: {keyword: "CRUDP", protocol: "Combat Radio User Datagram"}, - 128: {keyword: "SSCOPMCE", protocol: ""}, - 129: {keyword: "IPLT", protocol: ""}, - 130: {keyword: "SPS", protocol: "Secure Packet Shield"}, - 131: {keyword: "PIPE", protocol: "Private IP Encapsulation within IP"}, - 132: {keyword: "SCTP", protocol: "Stream Control Transmission Protocol"}, - 133: {keyword: "FC", protocol: "Fibre Channel"}, - 134: {keyword: "RSVP-E2E-IGNORE", protocol: ""}, - 135: {keyword: "Mobility Header", protocol: ""}, - 136: {keyword: "UDPLite", protocol: ""}, - 137: {keyword: "MPLS-in-IP", protocol: ""}, - 138: {keyword: "manet", protocol: "MANET Protocols"}, - 139: {keyword: "HIP", protocol: "Host Identity Protocol"}, - 140: {keyword: "Shim6", protocol: "Shim6 Protocol"}, - 141: {keyword: "WESP", protocol: "Wrapped Encapsulating Security Payload"}, - 142: {keyword: "ROHC", protocol: "Robust Header Compression"}, - 253: {keyword: "", protocol: "Use for experimentation and testing"}, - 254: {keyword: "", protocol: "Use for experimentation and testing"}, - 255: {keyword: "Reserved", protocol: ""} - }, - -}; - -export default IP; diff --git a/src/core/operations/legacy/MAC.js b/src/core/operations/legacy/MAC.js deleted file mode 100755 index b909287f..00000000 --- a/src/core/operations/legacy/MAC.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * MAC address operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const MAC = { - - /** - * @constant - * @default - */ - OUTPUT_CASE: ["Both", "Upper only", "Lower only"], - /** - * @constant - * @default - */ - NO_DELIM: true, - /** - * @constant - * @default - */ - DASH_DELIM: true, - /** - * @constant - * @default - */ - COLON_DELIM: true, - /** - * @constant - * @default - */ - CISCO_STYLE: false, - /** - * @constant - * @default - */ - IPV6_INTERFACE_ID: false, - - /** - * Format MAC addresses operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runFormat: function(input, args) { - if (!input) return ""; - - let outputCase = args[0], - noDelim = args[1], - dashDelim = args[2], - colonDelim = args[3], - ciscoStyle = args[4], - ipv6IntID = args[5], - outputList = [], - macs = input.toLowerCase().split(/[,\s\r\n]+/); - - macs.forEach(function(mac) { - let cleanMac = mac.replace(/[:.-]+/g, ""), - macHyphen = cleanMac.replace(/(.{2}(?=.))/g, "$1-"), - macColon = cleanMac.replace(/(.{2}(?=.))/g, "$1:"), - macCisco = cleanMac.replace(/(.{4}(?=.))/g, "$1."), - macIPv6 = cleanMac.slice(0, 6) + "fffe" + cleanMac.slice(6); - - macIPv6 = macIPv6.replace(/(.{4}(?=.))/g, "$1:"); - let bite = parseInt(macIPv6.slice(0, 2), 16) ^ 2; - bite = bite.toString(16).padStart(2, "0"); - macIPv6 = bite + macIPv6.slice(2); - - if (outputCase === "Lower only") { - if (noDelim) outputList.push(cleanMac); - if (dashDelim) outputList.push(macHyphen); - if (colonDelim) outputList.push(macColon); - if (ciscoStyle) outputList.push(macCisco); - if (ipv6IntID) outputList.push(macIPv6); - } else if (outputCase === "Upper only") { - if (noDelim) outputList.push(cleanMac.toUpperCase()); - if (dashDelim) outputList.push(macHyphen.toUpperCase()); - if (colonDelim) outputList.push(macColon.toUpperCase()); - if (ciscoStyle) outputList.push(macCisco.toUpperCase()); - if (ipv6IntID) outputList.push(macIPv6.toUpperCase()); - } else { - if (noDelim) outputList.push(cleanMac, cleanMac.toUpperCase()); - if (dashDelim) outputList.push(macHyphen, macHyphen.toUpperCase()); - if (colonDelim) outputList.push(macColon, macColon.toUpperCase()); - if (ciscoStyle) outputList.push(macCisco, macCisco.toUpperCase()); - if (ipv6IntID) outputList.push(macIPv6, macIPv6.toUpperCase()); - } - - outputList.push( - "" // Empty line to delimit groups - ); - }); - - // Return the data as a string - return outputList.join("\n"); - }, - -}; - -export default MAC; diff --git a/src/core/operations/legacy/MS.js b/src/core/operations/legacy/MS.js deleted file mode 100644 index a74dbe17..00000000 --- a/src/core/operations/legacy/MS.js +++ /dev/null @@ -1,213 +0,0 @@ -/** - * Microsoft operations. - * - * @author bmwhitn [brian.m.whitney@outlook.com] - * @copyright Crown Copyright 2017 - * @license Apache-2.0 - * - * @namespace - */ -const MS = { - - /** - * @constant - * @default - */ - D_DECODE: [ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "\x57\x6E\x7B", - "\x4A\x4C\x41", - "\x0B\x0B\x0B", - "\x0C\x0C\x0C", - "\x4A\x4C\x41", - "\x0E\x0E\x0E", - "\x0F\x0F\x0F", - "\x10\x10\x10", - "\x11\x11\x11", - "\x12\x12\x12", - "\x13\x13\x13", - "\x14\x14\x14", - "\x15\x15\x15", - "\x16\x16\x16", - "\x17\x17\x17", - "\x18\x18\x18", - "\x19\x19\x19", - "\x1A\x1A\x1A", - "\x1B\x1B\x1B", - "\x1C\x1C\x1C", - "\x1D\x1D\x1D", - "\x1E\x1E\x1E", - "\x1F\x1F\x1F", - "\x2E\x2D\x32", - "\x47\x75\x30", - "\x7A\x52\x21", - "\x56\x60\x29", - "\x42\x71\x5B", - "\x6A\x5E\x38", - "\x2F\x49\x33", - "\x26\x5C\x3D", - "\x49\x62\x58", - "\x41\x7D\x3A", - "\x34\x29\x35", - "\x32\x36\x65", - "\x5B\x20\x39", - "\x76\x7C\x5C", - "\x72\x7A\x56", - "\x43\x7F\x73", - "\x38\x6B\x66", - "\x39\x63\x4E", - "\x70\x33\x45", - "\x45\x2B\x6B", - "\x68\x68\x62", - "\x71\x51\x59", - "\x4F\x66\x78", - "\x09\x76\x5E", - "\x62\x31\x7D", - "\x44\x64\x4A", - "\x23\x54\x6D", - "\x75\x43\x71", - "\x4A\x4C\x41", - "\x7E\x3A\x60", - "\x4A\x4C\x41", - "\x5E\x7E\x53", - "\x40\x4C\x40", - "\x77\x45\x42", - "\x4A\x2C\x27", - "\x61\x2A\x48", - "\x5D\x74\x72", - "\x22\x27\x75", - "\x4B\x37\x31", - "\x6F\x44\x37", - "\x4E\x79\x4D", - "\x3B\x59\x52", - "\x4C\x2F\x22", - "\x50\x6F\x54", - "\x67\x26\x6A", - "\x2A\x72\x47", - "\x7D\x6A\x64", - "\x74\x39\x2D", - "\x54\x7B\x20", - "\x2B\x3F\x7F", - "\x2D\x38\x2E", - "\x2C\x77\x4C", - "\x30\x67\x5D", - "\x6E\x53\x7E", - "\x6B\x47\x6C", - "\x66\x34\x6F", - "\x35\x78\x79", - "\x25\x5D\x74", - "\x21\x30\x43", - "\x64\x23\x26", - "\x4D\x5A\x76", - "\x52\x5B\x25", - "\x63\x6C\x24", - "\x3F\x48\x2B", - "\x7B\x55\x28", - "\x78\x70\x23", - "\x29\x69\x41", - "\x28\x2E\x34", - "\x73\x4C\x09", - "\x59\x21\x2A", - "\x33\x24\x44", - "\x7F\x4E\x3F", - "\x6D\x50\x77", - "\x55\x09\x3B", - "\x53\x56\x55", - "\x7C\x73\x69", - "\x3A\x35\x61", - "\x5F\x61\x63", - "\x65\x4B\x50", - "\x46\x58\x67", - "\x58\x3B\x51", - "\x31\x57\x49", - "\x69\x22\x4F", - "\x6C\x6D\x46", - "\x5A\x4D\x68", - "\x48\x25\x7C", - "\x27\x28\x36", - "\x5C\x46\x70", - "\x3D\x4A\x6E", - "\x24\x32\x7A", - "\x79\x41\x2F", - "\x37\x3D\x5F", - "\x60\x5F\x4B", - "\x51\x4F\x5A", - "\x20\x42\x2C", - "\x36\x65\x57" - ], - - /** - * @constant - * @default - */ - D_COMBINATION: [ - 0, 1, 2, 0, 1, 2, 1, 2, 2, 1, 2, 1, 0, 2, 1, 2, 0, 2, 1, 2, 0, 0, 1, 2, 2, 1, 0, 2, 1, 2, 2, 1, - 0, 0, 2, 1, 2, 1, 2, 0, 2, 0, 0, 1, 2, 0, 2, 1, 0, 2, 1, 2, 0, 0, 1, 2, 2, 0, 0, 1, 2, 0, 2, 1 - ], - - - /** - * Decodes Microsoft Encoded Script files that can be read and executed by cscript.exe/wscript.exe. - * This is a conversion of a Python script that was originally created by Didier Stevens - * (https://DidierStevens.com). - * - * @private - * @param {string} data - * @returns {string} - */ - _decode: function (data) { - let result = []; - let index = -1; - data = data.replace(/@&/g, String.fromCharCode(10)) - .replace(/@#/g, String.fromCharCode(13)) - .replace(/@\*/g, ">") - .replace(/@!/g, "<") - .replace(/@\$/g, "@"); - - for (let i = 0; i < data.length; i++) { - let byte = data.charCodeAt(i); - let char = data.charAt(i); - if (byte < 128) { - index++; - } - - if ((byte === 9 || byte > 31 && byte < 128) && - byte !== 60 && - byte !== 62 && - byte !== 64) { - char = MS.D_DECODE[byte].charAt(MS.D_COMBINATION[index % 64]); - } - result.push(char); - } - return result.join(""); - }, - - - /** - * Microsoft Script Decoder operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runDecodeScript: function (input, args) { - let matcher = /#@~\^.{6}==(.+).{6}==\^#~@/; - let encodedData = matcher.exec(input); - if (encodedData){ - return MS._decode(encodedData[1]); - } else { - return ""; - } - } - -}; - -export default MS; diff --git a/src/core/operations/legacy/MorseCode.js b/src/core/operations/legacy/MorseCode.js deleted file mode 100644 index de81ce89..00000000 --- a/src/core/operations/legacy/MorseCode.js +++ /dev/null @@ -1,190 +0,0 @@ -import Utils from "../Utils.js"; - - -/** - * Morse Code translation operations. - * - * @author tlwr [toby@toby.codes] - * @copyright Crown Copyright 2017 - * @license Apache-2.0 - * - * @namespace - */ -const MorseCode = { - - /** - * @constant - * @default - */ - FORMAT_OPTIONS: ["-/.", "_/.", "Dash/Dot", "DASH/DOT", "dash/dot"], - /** - * @constant - * @default - */ - LETTER_DELIM_OPTIONS: ["Space", "Line feed", "CRLF", "Forward slash", "Backslash", "Comma", "Semi-colon", "Colon"], - /** - * @constant - * @default - */ - WORD_DELIM_OPTIONS: ["Line feed", "CRLF", "Forward slash", "Backslash", "Comma", "Semi-colon", "Colon"], - /** - * @constant - * @default - */ - MORSE_TABLE: { - "A": "", - "B": "", - "C": "", - "D": "", - "E": "", - "F": "", - "G": "", - "H": "", - "I": "", - "J": "", - "K": "", - "L": "", - "M": "", - "N": "", - "O": "", - "P": "", - "Q": "", - "R": "", - "S": "", - "T": "", - "U": "", - "V": "", - "W": "", - "X": "", - "Y": "", - "Z": "", - "1": "", - "2": "", - "3": "", - "4": "", - "5": "", - "6": "", - "7": "", - "8": "", - "9": "", - "0": "", - ".": "", - ",": "", - ":": "", - ";": "", - "!": "", - "?": "", - "'": "", - "\"": "", - "/": "", - "-": "", - "+": "", - "(": "", - ")": "", - "@": "", - "=": "", - "&": "", - "_": "", - "$": "" - }, - - - /** - * To Morse Code operation. - * - * @param {number} input - * @param {Object[]} args - * @returns {string} - */ - runTo: function(input, args) { - const format = args[0].split("/"); - const dash = format[0]; - const dot = format[1]; - - const letterDelim = Utils.charRep(args[1]); - const wordDelim = Utils.charRep(args[2]); - - input = input.split(/\r?\n/); - input = Array.prototype.map.call(input, function(line) { - let words = line.split(/ +/); - words = Array.prototype.map.call(words, function(word) { - const letters = Array.prototype.map.call(word, function(character) { - const letter = character.toUpperCase(); - if (typeof MorseCode.MORSE_TABLE[letter] == "undefined") { - return ""; - } - - return MorseCode.MORSE_TABLE[letter]; - }); - - return letters.join(""); - }); - line = words.join(""); - return line; - }); - input = input.join("\n"); - - input = input.replace( - /|||/g, - function(match) { - switch (match) { - case "": return dash; - case "": return dot; - case "": return letterDelim; - case "": return wordDelim; - } - } - ); - - return input; - }, - - - /** - * From Morse Code operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runFrom: (function() { - let reversedTable = null; - const reverseTable = function() { - reversedTable = {}; - - for (const letter in MorseCode.MORSE_TABLE) { - const signal = MorseCode.MORSE_TABLE[letter]; - reversedTable[signal] = letter; - } - }; - - return function(input, args) { - if (reversedTable === null) { - reverseTable(); - } - - const letterDelim = Utils.charRep(args[0]); - const wordDelim = Utils.charRep(args[1]); - - input = input.replace(/-|‐|−|_|–|—|dash/ig, ""); //hyphen-minus|hyphen|minus-sign|undersore|en-dash|em-dash - input = input.replace(/\.|·|dot/ig, ""); - - let words = input.split(wordDelim); - words = Array.prototype.map.call(words, function(word) { - const signals = word.split(letterDelim); - - const letters = signals.map(function(signal) { - return reversedTable[signal]; - }); - - return letters.join(""); - }); - words = words.join(" "); - - return words; - }; - })(), - -}; - -export default MorseCode; diff --git a/src/core/operations/legacy/NetBIOS.js b/src/core/operations/legacy/NetBIOS.js deleted file mode 100644 index 60866b65..00000000 --- a/src/core/operations/legacy/NetBIOS.js +++ /dev/null @@ -1,70 +0,0 @@ -/** - * NetBIOS operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2017 - * @license Apache-2.0 - * - * @namespace - */ -const NetBIOS = { - - /** - * @constant - * @default - */ - OFFSET: 65, - - /** - * Encode NetBIOS Name operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {byteArray} - */ - runEncodeName: function(input, args) { - let output = [], - offset = args[0]; - - if (input.length <= 16) { - let len = input.length; - input.length = 16; - input.fill(32, len, 16); - for (let i = 0; i < input.length; i++) { - output.push((input[i] >> 4) + offset); - output.push((input[i] & 0xf) + offset); - } - } - - return output; - }, - - - /** - * Decode NetBIOS Name operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {byteArray} - */ - runDecodeName: function(input, args) { - let output = [], - offset = args[0]; - - if (input.length <= 32 && (input.length % 2) === 0) { - for (let i = 0; i < input.length; i += 2) { - output.push((((input[i] & 0xff) - offset) << 4) | - (((input[i + 1] & 0xff) - offset) & 0xf)); - } - for (let i = output.length - 1; i > 0; i--) { - if (output[i] === 32) output.splice(i, i); - else break; - } - } - - return output; - }, - -}; - -export default NetBIOS; diff --git a/src/core/operations/legacy/Numberwang.js b/src/core/operations/legacy/Numberwang.js deleted file mode 100755 index e323f74c..00000000 --- a/src/core/operations/legacy/Numberwang.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Numberwang operations. - * - * @author Unknown Male 282 - * @namespace - */ -const Numberwang = { - - /** - * Numberwang operation. Remain indoors. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - run: function(input, args) { - let output; - if (!input) { - output = "Let's play Wangernumb!"; - } else { - const match = input.match(/(f0rty-s1x|shinty-six|filth-hundred and neeb|-?√?\d+(\.\d+)?i?([a-z]?)%?)/i); - if (match) { - if (match[3]) output = match[0] + "! That's AlphaNumericWang!"; - else output = match[0] + "! That's Numberwang!"; - } else { - // That's a bad miss! - output = "Sorry, that's not Numberwang. Let's rotate the board!"; - } - } - - const rand = Math.floor(Math.random() * Numberwang._didYouKnow.length); - return output + "\n\nDid you know: " + Numberwang._didYouKnow[rand]; - }, - - - /** - * Taken from http://numberwang.wikia.com/wiki/Numberwang_Wikia - * - * @private - * @constant - */ - _didYouKnow: [ - "Numberwang, contrary to popular belief, is a fruit and not a vegetable.", - "Robert Webb once got WordWang while presenting an episode of Numberwang.", - "The 6705th digit of pi is Numberwang.", - "Numberwang was invented on a Sevenday.", - "Contrary to popular belief, Albert Einstein always got good grades in Numberwang at school. He once scored ^4$ on a test.", - "680 asteroids have been named after Numberwang.", - "Archimedes is most famous for proclaiming \"That's Numberwang!\" during an epiphany about water displacement he had while taking a bath.", - "Numberwang Day is celebrated in Japan on every day of the year apart from June 6.", - "Biologists recently discovered Numberwang within a strand of human DNA.", - "Numbernot is a special type of non-Numberwang number. It is divisible by 3 and the letter \"y\".", - "Julie once got 612.04 Numberwangs in a single episode of Emmerdale.", - "In India, it is traditional to shout out \"Numberwang!\" instead of checkmate during games of chess.", - "There is a rule on Countdown which states that if you get Numberwang in the numbers round, you automatically win. It has only ever been invoked twice.", - "\"Numberwang\" was the third-most common baby name for a brief period in 1722.", - "\"The Lion King\" was loosely based on Numberwang.", - "\"A Numberwang a day keeps the doctor away\" is how Donny Cosy, the oldest man in the world, explained how he was in such good health at the age of 136.", - "The \"number lock\" button on a keyboard is based on the popular round of the same name in \"Numberwang\".", - "Cambridge became the first university to offer a course in Numberwang in 1567.", - "Schrödinger's Numberwang is a number that has been confusing dentists for centuries.", - "\"Harry Potter and the Numberwang of Numberwang\" was rejected by publishers -41 times before it became a bestseller.", - "\"Numberwang\" is the longest-running British game show in history; it has aired 226 seasons, each containing 19 episodes, which makes a grand total of 132 episodes.", - "The triple Numberwang bonus was discovered by archaeologist Thomas Jefferson in Somerset.", - "Numberwang is illegal in parts of Czechoslovakia.", - "Numberwang was discovered in India in the 12th century.", - "Numberwang has the chemical formula Zn4SO2(HgEs)3.", - "The first pack of cards ever created featured two \"Numberwang\" cards instead of jokers.", - "Julius Caesar was killed by an overdose of Numberwang.", - "The most Numberwang musical note is G#.", - "In 1934, the forty-third Google Doodle promoted the upcoming television show \"Numberwang on Ice\".", - "A recent psychology study found that toddlers were 17% faster at identifying numbers which were Numberwang.", - "There are 700 ways to commit a foul in the television show \"Numberwang\". All 700 of these fouls were committed by Julie in one single episode in 1473.", - "Astronomers suspect God is Numberwang.", - "Numberwang is the official beverage of Canada.", - "In the pilot episode of \"The Price is Right\", if a contestant got the value of an item exactly right they were told \"That's Numberwang!\" and immediately won ₹5.7032.", - "The first person to get three Numberwangs in a row was Madonna.", - "\"Numberwang\" has the code U+46402 in Unicode.", - "The musical note \"Numberwang\" is between D# and E♮.", - "Numberwang was first played on the moon in 1834.", - ], - -}; - -export default Numberwang; diff --git a/src/core/operations/legacy/OS.js b/src/core/operations/legacy/OS.js deleted file mode 100755 index 93a780f1..00000000 --- a/src/core/operations/legacy/OS.js +++ /dev/null @@ -1,311 +0,0 @@ -/** - * Operating system operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const OS = { - - /** - * Parse UNIX file permissions operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runParseUnixPerms: function(input, args) { - let perms = { - d: false, // directory - sl: false, // symbolic link - np: false, // named pipe - s: false, // socket - cd: false, // character device - bd: false, // block device - dr: false, // door - sb: false, // sticky bit - su: false, // setuid - sg: false, // setgid - ru: false, // read user - wu: false, // write user - eu: false, // execute user - rg: false, // read group - wg: false, // write group - eg: false, // execute group - ro: false, // read other - wo: false, // write other - eo: false // execute other - }, - d = 0, - u = 0, - g = 0, - o = 0, - output = "", - octal = null, - textual = null; - - if (input.search(/\s*[0-7]{1,4}\s*/i) === 0) { - // Input is octal - octal = input.match(/\s*([0-7]{1,4})\s*/i)[1]; - - if (octal.length === 4) { - d = parseInt(octal[0], 8); - u = parseInt(octal[1], 8); - g = parseInt(octal[2], 8); - o = parseInt(octal[3], 8); - } else { - if (octal.length > 0) u = parseInt(octal[0], 8); - if (octal.length > 1) g = parseInt(octal[1], 8); - if (octal.length > 2) o = parseInt(octal[2], 8); - } - - perms.su = d >> 2 & 0x1; - perms.sg = d >> 1 & 0x1; - perms.sb = d & 0x1; - - perms.ru = u >> 2 & 0x1; - perms.wu = u >> 1 & 0x1; - perms.eu = u & 0x1; - - perms.rg = g >> 2 & 0x1; - perms.wg = g >> 1 & 0x1; - perms.eg = g & 0x1; - - perms.ro = o >> 2 & 0x1; - perms.wo = o >> 1 & 0x1; - perms.eo = o & 0x1; - } else if (input.search(/\s*[dlpcbDrwxsStT-]{1,10}\s*/) === 0) { - // Input is textual - textual = input.match(/\s*([dlpcbDrwxsStT-]{1,10})\s*/)[1]; - - switch (textual[0]) { - case "d": - perms.d = true; - break; - case "l": - perms.sl = true; - break; - case "p": - perms.np = true; - break; - case "s": - perms.s = true; - break; - case "c": - perms.cd = true; - break; - case "b": - perms.bd = true; - break; - case "D": - perms.dr = true; - break; - } - - if (textual.length > 1) perms.ru = textual[1] === "r"; - if (textual.length > 2) perms.wu = textual[2] === "w"; - if (textual.length > 3) { - switch (textual[3]) { - case "x": - perms.eu = true; - break; - case "s": - perms.eu = true; - perms.su = true; - break; - case "S": - perms.su = true; - break; - } - } - - if (textual.length > 4) perms.rg = textual[4] === "r"; - if (textual.length > 5) perms.wg = textual[5] === "w"; - if (textual.length > 6) { - switch (textual[6]) { - case "x": - perms.eg = true; - break; - case "s": - perms.eg = true; - perms.sg = true; - break; - case "S": - perms.sg = true; - break; - } - } - - if (textual.length > 7) perms.ro = textual[7] === "r"; - if (textual.length > 8) perms.wo = textual[8] === "w"; - if (textual.length > 9) { - switch (textual[9]) { - case "x": - perms.eo = true; - break; - case "t": - perms.eo = true; - perms.sb = true; - break; - case "T": - perms.sb = true; - break; - } - } - } else { - return "Invalid input format.\nPlease enter the permissions in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format."; - } - - output += "Textual representation: " + OS._permsToStr(perms); - output += "\nOctal representation: " + OS._permsToOctal(perms); - - // File type - if (textual) { - output += "\nFile type: " + OS._ftFromPerms(perms); - } - - // setuid, setgid - if (perms.su) { - output += "\nThe setuid flag is set"; - } - if (perms.sg) { - output += "\nThe setgid flag is set"; - } - - // sticky bit - if (perms.sb) { - output += "\nThe sticky bit is set"; - } - - // Permission matrix - output += "\n\n +---------+-------+-------+-------+\n" + - " | | User | Group | Other |\n" + - " +---------+-------+-------+-------+\n" + - " | Read | " + (perms.ru ? "X" : " ") + " | " + (perms.rg ? "X" : " ") + " | " + (perms.ro ? "X" : " ") + " |\n" + - " +---------+-------+-------+-------+\n" + - " | Write | " + (perms.wu ? "X" : " ") + " | " + (perms.wg ? "X" : " ") + " | " + (perms.wo ? "X" : " ") + " |\n" + - " +---------+-------+-------+-------+\n" + - " | Execute | " + (perms.eu ? "X" : " ") + " | " + (perms.eg ? "X" : " ") + " | " + (perms.eo ? "X" : " ") + " |\n" + - " +---------+-------+-------+-------+\n"; - - return output; - }, - - - /** - * Given a permissions object dictionary, generates a textual permissions string. - * - * @private - * @param {Object} perms - * @returns {string} - */ - _permsToStr: function(perms) { - let str = "", - type = "-"; - - if (perms.d) type = "d"; - if (perms.sl) type = "l"; - if (perms.np) type = "p"; - if (perms.s) type = "s"; - if (perms.cd) type = "c"; - if (perms.bd) type = "b"; - if (perms.dr) type = "D"; - - str = type; - - str += perms.ru ? "r" : "-"; - str += perms.wu ? "w" : "-"; - if (perms.eu && perms.su) { - str += "s"; - } else if (perms.su) { - str += "S"; - } else if (perms.eu) { - str += "x"; - } else { - str += "-"; - } - - str += perms.rg ? "r" : "-"; - str += perms.wg ? "w" : "-"; - if (perms.eg && perms.sg) { - str += "s"; - } else if (perms.sg) { - str += "S"; - } else if (perms.eg) { - str += "x"; - } else { - str += "-"; - } - - str += perms.ro ? "r" : "-"; - str += perms.wo ? "w" : "-"; - if (perms.eo && perms.sb) { - str += "t"; - } else if (perms.sb) { - str += "T"; - } else if (perms.eo) { - str += "x"; - } else { - str += "-"; - } - - return str; - }, - - - /** - * Given a permissions object dictionary, generates an octal permissions string. - * - * @private - * @param {Object} perms - * @returns {string} - */ - _permsToOctal: function(perms) { - let d = 0, - u = 0, - g = 0, - o = 0; - - if (perms.su) d += 4; - if (perms.sg) d += 2; - if (perms.sb) d += 1; - - if (perms.ru) u += 4; - if (perms.wu) u += 2; - if (perms.eu) u += 1; - - if (perms.rg) g += 4; - if (perms.wg) g += 2; - if (perms.eg) g += 1; - - if (perms.ro) o += 4; - if (perms.wo) o += 2; - if (perms.eo) o += 1; - - return d.toString() + u.toString() + g.toString() + o.toString(); - }, - - - /** - * Given a permissions object dictionary, returns the file type. - * - * @private - * @param {Object} perms - * @returns {string} - */ - _ftFromPerms: function(perms) { - if (perms.d) return "Directory"; - if (perms.sl) return "Symbolic link"; - if (perms.np) return "Named pipe"; - if (perms.s) return "Socket"; - if (perms.cd) return "Character device"; - if (perms.bd) return "Block device"; - if (perms.dr) return "Door"; - return "Regular file"; - }, - -}; - -export default OS; diff --git a/src/core/operations/legacy/OTP.js b/src/core/operations/legacy/OTP.js deleted file mode 100755 index f7862310..00000000 --- a/src/core/operations/legacy/OTP.js +++ /dev/null @@ -1,56 +0,0 @@ -import otp from "otp"; -import Base64 from "./Base64.js"; - - -/** - * One-Time Password operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2017 - * @license Apache-2.0 - * - * @namespace - */ -const OTP = { - - /** - * Generate TOTP operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runTOTP: function(input, args) { - const otpObj = otp({ - name: args[0], - keySize: args[1], - codeLength: args[2], - secret: Base64.runTo32(input, []), - epoch: args[3], - timeSlice: args[4] - }); - return `URI: ${otpObj.totpURL}\n\nPassword: ${otpObj.totp()}`; - }, - - - /** - * Generate HOTP operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runHOTP: function(input, args) { - const otpObj = otp({ - name: args[0], - keySize: args[1], - codeLength: args[2], - secret: Base64.runTo32(input, []), - }); - const counter = args[3]; - return `URI: ${otpObj.hotpURL}\n\nPassword: ${otpObj.hotp(counter)}`; - }, - -}; - -export default OTP; diff --git a/src/core/operations/legacy/PHP.js b/src/core/operations/legacy/PHP.js deleted file mode 100644 index e4bb0b5b..00000000 --- a/src/core/operations/legacy/PHP.js +++ /dev/null @@ -1,160 +0,0 @@ -/** - * PHP operations. - * - * @author Jarmo van Lenthe [github.com/jarmovanlenthe] - * @copyright Jarmo van Lenthe - * @license Apache-2.0 - * - * @namespace - */ -const PHP = { - - /** - * @constant - * @default - */ - OUTPUT_VALID_JSON: true, - - /** - * PHP Deserialize operation. - * - * This Javascript implementation is based on the Python implementation by - * Armin Ronacher (2016), who released it under the 3-Clause BSD license. - * See: https://github.com/mitsuhiko/phpserialize/ - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runDeserialize: function (input, args) { - /** - * Recursive method for deserializing. - * @returns {*} - */ - function handleInput() { - /** - * Read `length` characters from the input, shifting them out the input. - * @param length - * @returns {string} - */ - function read(length) { - let result = ""; - for (let idx = 0; idx < length; idx++) { - let char = inputPart.shift(); - if (char === undefined) { - throw "End of input reached before end of script"; - } - result += char; - } - return result; - } - - /** - * Read characters from the input until `until` is found. - * @param until - * @returns {string} - */ - function readUntil(until) { - let result = ""; - for (;;) { - let char = read(1); - if (char === until) { - break; - } else { - result += char; - } - } - return result; - - } - - /** - * Read characters from the input that must be equal to `expect` - * @param expect - * @returns {string} - */ - function expect(expect) { - let result = read(expect.length); - if (result !== expect) { - throw "Unexpected input found"; - } - return result; - } - - /** - * Helper function to handle deserialized arrays. - * @returns {Array} - */ - function handleArray() { - let items = parseInt(readUntil(":"), 10) * 2; - expect("{"); - let result = []; - let isKey = true; - let lastItem = null; - for (let idx = 0; idx < items; idx++) { - let item = handleInput(); - if (isKey) { - lastItem = item; - isKey = false; - } else { - let numberCheck = lastItem.match(/[0-9]+/); - if (args[0] && numberCheck && numberCheck[0].length === lastItem.length) { - result.push("\"" + lastItem + "\": " + item); - } else { - result.push(lastItem + ": " + item); - } - isKey = true; - } - } - expect("}"); - return result; - } - - - let kind = read(1).toLowerCase(); - - switch (kind) { - case "n": - expect(";"); - return ""; - - case "i": - case "d": - case "b": { - expect(":"); - let data = readUntil(";"); - if (kind === "b") { - return (parseInt(data, 10) !== 0); - } - return data; - } - - case "a": - expect(":"); - return "{" + handleArray() + "}"; - - case "s": { - expect(":"); - let length = readUntil(":"); - expect("\""); - let value = read(length); - expect("\";"); - if (args[0]) { - return "\"" + value.replace(/"/g, "\\\"") + "\""; - } else { - return "\"" + value + "\""; - } - } - - default: - throw "Unknown type: " + kind; - } - } - - let inputPart = input.split(""); - return handleInput(); - } - -}; - -export default PHP; diff --git a/src/core/operations/legacy/PublicKey.js b/src/core/operations/legacy/PublicKey.js deleted file mode 100755 index a52caf25..00000000 --- a/src/core/operations/legacy/PublicKey.js +++ /dev/null @@ -1,348 +0,0 @@ -import Utils from "../Utils.js"; -import {fromBase64} from "../lib/Base64"; -import {toHex, fromHex} from "../lib/Hex"; -import * as r from "jsrsasign"; - - -/** - * Public Key operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const PublicKey = { - - /** - * @constant - * @default - */ - X509_INPUT_FORMAT: ["PEM", "DER Hex", "Base64", "Raw"], - - /** - * Parse X.509 certificate operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runParseX509: function (input, args) { - if (!input.length) { - return "No input"; - } - - let cert = new r.X509(), - inputFormat = args[0]; - - switch (inputFormat) { - case "DER Hex": - input = input.replace(/\s/g, ""); - cert.readCertHex(input); - break; - case "PEM": - cert.readCertPEM(input); - break; - case "Base64": - cert.readCertHex(toHex(fromBase64(input, null, "byteArray"), "")); - break; - case "Raw": - cert.readCertHex(toHex(Utils.strToByteArray(input), "")); - break; - default: - throw "Undefined input format"; - } - - let sn = cert.getSerialNumberHex(), - issuer = cert.getIssuerString(), - subject = cert.getSubjectString(), - pk = cert.getPublicKey(), - pkFields = [], - pkStr = "", - sig = cert.getSignatureValueHex(), - sigStr = "", - extensions = ""; - - // Public Key fields - pkFields.push({ - key: "Algorithm", - value: pk.type - }); - - if (pk.type === "EC") { // ECDSA - pkFields.push({ - key: "Curve Name", - value: pk.curveName - }); - pkFields.push({ - key: "Length", - value: (((new r.BigInteger(pk.pubKeyHex, 16)).bitLength()-3) /2) + " bits" - }); - pkFields.push({ - key: "pub", - value: PublicKey._formatByteStr(pk.pubKeyHex, 16, 18) - }); - } else if (pk.type === "DSA") { // DSA - pkFields.push({ - key: "pub", - value: PublicKey._formatByteStr(pk.y.toString(16), 16, 18) - }); - pkFields.push({ - key: "P", - value: PublicKey._formatByteStr(pk.p.toString(16), 16, 18) - }); - pkFields.push({ - key: "Q", - value: PublicKey._formatByteStr(pk.q.toString(16), 16, 18) - }); - pkFields.push({ - key: "G", - value: PublicKey._formatByteStr(pk.g.toString(16), 16, 18) - }); - } else if (pk.e) { // RSA - pkFields.push({ - key: "Length", - value: pk.n.bitLength() + " bits" - }); - pkFields.push({ - key: "Modulus", - value: PublicKey._formatByteStr(pk.n.toString(16), 16, 18) - }); - pkFields.push({ - key: "Exponent", - value: pk.e + " (0x" + pk.e.toString(16) + ")" - }); - } else { - pkFields.push({ - key: "Error", - value: "Unknown Public Key type" - }); - } - - // Format Public Key fields - for (let i = 0; i < pkFields.length; i++) { - pkStr += " " + pkFields[i].key + ":" + - (pkFields[i].value + "\n").padStart( - 18 - (pkFields[i].key.length + 3) + pkFields[i].value.length + 1, - " " - ); - } - - // Signature fields - let breakoutSig = false; - try { - breakoutSig = r.ASN1HEX.dump(sig).indexOf("SEQUENCE") === 0; - } catch (err) { - // Error processing signature, output without further breakout - } - - if (breakoutSig) { // DSA or ECDSA - sigStr = " r: " + PublicKey._formatByteStr(r.ASN1HEX.getV(sig, 4), 16, 18) + "\n" + - " s: " + PublicKey._formatByteStr(r.ASN1HEX.getV(sig, 48), 16, 18); - } else { // RSA or unknown - sigStr = " Signature: " + PublicKey._formatByteStr(sig, 16, 18); - } - - // Extensions - try { - extensions = cert.getInfo().split("X509v3 Extensions:\n")[1].split("signature")[0]; - } catch (err) {} - - let issuerStr = PublicKey._formatDnStr(issuer, 2), - nbDate = PublicKey._formatDate(cert.getNotBefore()), - naDate = PublicKey._formatDate(cert.getNotAfter()), - subjectStr = PublicKey._formatDnStr(subject, 2); - - return `Version: ${cert.version} (0x${Utils.hex(cert.version - 1)}) -Serial number: ${new r.BigInteger(sn, 16).toString()} (0x${sn}) -Algorithm ID: ${cert.getSignatureAlgorithmField()} -Validity - Not Before: ${nbDate} (dd-mm-yy hh:mm:ss) (${cert.getNotBefore()}) - Not After: ${naDate} (dd-mm-yy hh:mm:ss) (${cert.getNotAfter()}) -Issuer -${issuerStr} -Subject -${subjectStr} -Public Key -${pkStr.slice(0, -1)} -Certificate Signature - Algorithm: ${cert.getSignatureAlgorithmName()} -${sigStr} - -Extensions -${extensions}`; - }, - - - /** - * PEM to Hex operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runPemToHex: function(input, args) { - if (input.indexOf("-----BEGIN") < 0) { - // Add header so that the KEYUTIL function works - input = "-----BEGIN CERTIFICATE-----" + input; - } - if (input.indexOf("-----END") < 0) { - // Add footer so that the KEYUTIL function works - input = input + "-----END CERTIFICATE-----"; - } - let cert = new r.X509(); - cert.readCertPEM(input); - return cert.hex; - }, - - - /** - * @constant - * @default - */ - PEM_HEADER_STRING: "CERTIFICATE", - - /** - * Hex to PEM operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runHexToPem: function(input, args) { - return r.KJUR.asn1.ASN1Util.getPEMStringFromHex(input.replace(/\s/g, ""), args[0]); - }, - - - /** - * Hex to Object Identifier operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runHexToObjectIdentifier: function(input, args) { - return r.KJUR.asn1.ASN1Util.oidHexToInt(input.replace(/\s/g, "")); - }, - - - /** - * Object Identifier to Hex operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runObjectIdentifierToHex: function(input, args) { - return r.KJUR.asn1.ASN1Util.oidIntToHex(input); - }, - - - /** - * @constant - * @default - */ - ASN1_TRUNCATE_LENGTH: 32, - - /** - * Parse ASN.1 hex string operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runParseAsn1HexString: function(input, args) { - let truncateLen = args[1], - index = args[0]; - return r.ASN1HEX.dump(input.replace(/\s/g, ""), { - "ommitLongOctet": truncateLen - }, index); - }, - - - /** - * Formats Distinguished Name (DN) strings. - * - * @private - * @param {string} dnStr - * @param {number} indent - * @returns {string} - */ - _formatDnStr: function(dnStr, indent) { - let output = "", - fields = dnStr.substr(1).replace(/([^\\])\//g, "$1$1/").split(/[^\\]\//), - maxKeyLen = 0, - key, - value, - i, - str; - - for (i = 0; i < fields.length; i++) { - if (!fields[i].length) continue; - - key = fields[i].split("=")[0]; - - maxKeyLen = key.length > maxKeyLen ? key.length : maxKeyLen; - } - - for (i = 0; i < fields.length; i++) { - if (!fields[i].length) continue; - - key = fields[i].split("=")[0]; - value = fields[i].split("=")[1]; - str = key.padEnd(maxKeyLen, " ") + " = " + value + "\n"; - - output += str.padStart(indent + str.length, " "); - } - - return output.slice(0, -1); - }, - - - /** - * Formats byte strings by adding line breaks and delimiters. - * - * @private - * @param {string} byteStr - * @param {number} length - Line width - * @param {number} indent - * @returns {string} - */ - _formatByteStr: function(byteStr, length, indent) { - byteStr = toHex(fromHex(byteStr), ":"); - length = length * 3; - let output = ""; - - for (let i = 0; i < byteStr.length; i += length) { - const str = byteStr.slice(i, i + length) + "\n"; - if (i === 0) { - output += str; - } else { - output += str.padStart(indent + str.length, " "); - } - } - - return output.slice(0, output.length-1); - }, - - - /** - * Formats dates. - * - * @private - * @param {string} dateStr - * @returns {string} - */ - _formatDate: function(dateStr) { - return dateStr[4] + dateStr[5] + "/" + - dateStr[2] + dateStr[3] + "/" + - dateStr[0] + dateStr[1] + " " + - dateStr[6] + dateStr[7] + ":" + - dateStr[8] + dateStr[9] + ":" + - dateStr[10] + dateStr[11]; - }, - -}; - -export default PublicKey; diff --git a/src/core/operations/legacy/Punycode.js b/src/core/operations/legacy/Punycode.js deleted file mode 100755 index d3f94e69..00000000 --- a/src/core/operations/legacy/Punycode.js +++ /dev/null @@ -1,58 +0,0 @@ -import punycode from "punycode"; - - -/** - * Punycode operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Punycode = { - - /** - * @constant - * @default - */ - IDN: false, - - /** - * To Punycode operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runToAscii: function(input, args) { - const idn = args[0]; - - if (idn) { - return punycode.toASCII(input); - } else { - return punycode.encode(input); - } - }, - - - /** - * From Punycode operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runToUnicode: function(input, args) { - const idn = args[0]; - - if (idn) { - return punycode.toUnicode(input); - } else { - return punycode.decode(input); - } - }, - -}; - -export default Punycode; diff --git a/src/core/operations/legacy/QuotedPrintable.js b/src/core/operations/legacy/QuotedPrintable.js deleted file mode 100755 index a53ea0ca..00000000 --- a/src/core/operations/legacy/QuotedPrintable.js +++ /dev/null @@ -1,272 +0,0 @@ -/** @license -======================================================================== - mimelib: http://github.com/andris9/mimelib - Copyright (c) 2011-2012 Andris Reinman - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -*/ - -/** - * Quoted Printable operations. - * Some parts taken from mimelib (http://github.com/andris9/mimelib) - * - * @author Andris Reinman - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const QuotedPrintable = { - - /** - * To Quoted Printable operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {string} - */ - runTo: function (input, args) { - let mimeEncodedStr = QuotedPrintable.mimeEncode(input); - - // fix line breaks - mimeEncodedStr = mimeEncodedStr.replace(/\r?\n|\r/g, function() { - return "\r\n"; - }).replace(/[\t ]+$/gm, function(spaces) { - return spaces.replace(/ /g, "=20").replace(/\t/g, "=09"); - }); - - return QuotedPrintable._addSoftLinebreaks(mimeEncodedStr, "qp"); - }, - - - /** - * From Quoted Printable operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {byteArray} - */ - runFrom: function (input, args) { - const str = input.replace(/=(?:\r?\n|$)/g, ""); - return QuotedPrintable.mimeDecode(str); - }, - - - /** - * Decodes mime-encoded data. - * - * @param {string} str - * @returns {byteArray} - */ - mimeDecode: function(str) { - let encodedBytesCount = (str.match(/=[\da-fA-F]{2}/g) || []).length, - bufferLength = str.length - encodedBytesCount * 2, - chr, hex, - buffer = new Array(bufferLength), - bufferPos = 0; - - for (let i = 0, len = str.length; i < len; i++) { - chr = str.charAt(i); - if (chr === "=" && (hex = str.substr(i + 1, 2)) && /[\da-fA-F]{2}/.test(hex)) { - buffer[bufferPos++] = parseInt(hex, 16); - i += 2; - continue; - } - buffer[bufferPos++] = chr.charCodeAt(0); - } - - return buffer; - }, - - - /** - * Encodes mime data. - * - * @param {byteArray} buffer - * @returns {string} - */ - mimeEncode: function(buffer) { - let ranges = [ - [0x09], - [0x0A], - [0x0D], - [0x20], - [0x21], - [0x23, 0x3C], - [0x3E], - [0x40, 0x5E], - [0x60, 0x7E] - ], - result = ""; - - for (let i = 0, len = buffer.length; i < len; i++) { - if (this._checkRanges(buffer[i], ranges)) { - result += String.fromCharCode(buffer[i]); - continue; - } - result += "=" + (buffer[i] < 0x10 ? "0" : "") + buffer[i].toString(16).toUpperCase(); - } - - return result; - }, - - - /** - * Checks if a given number falls within a given set of ranges. - * - * @private - * @param {number} nr - * @param {byteArray[]} ranges - * @returns {bolean} - */ - _checkRanges: function(nr, ranges) { - for (let i = ranges.length - 1; i >= 0; i--) { - if (!ranges[i].length) - continue; - if (ranges[i].length === 1 && nr === ranges[i][0]) - return true; - if (ranges[i].length === 2 && nr >= ranges[i][0] && nr <= ranges[i][1]) - return true; - } - return false; - }, - - - /** - * Adds soft line breaks to a string. - * Lines can't be longer that 76 + = 78 bytes - * http://tools.ietf.org/html/rfc2045#section-6.7 - * - * @private - * @param {string} str - * @param {string} encoding - * @returns {string} - */ - _addSoftLinebreaks: function(str, encoding) { - const lineLengthMax = 76; - - encoding = (encoding || "base64").toString().toLowerCase().trim(); - - if (encoding === "qp") { - return this._addQPSoftLinebreaks(str, lineLengthMax); - } else { - return this._addBase64SoftLinebreaks(str, lineLengthMax); - } - }, - - - /** - * Adds soft line breaks to a base64 string. - * - * @private - * @param {string} base64EncodedStr - * @param {number} lineLengthMax - * @returns {string} - */ - _addBase64SoftLinebreaks: function(base64EncodedStr, lineLengthMax) { - base64EncodedStr = (base64EncodedStr || "").toString().trim(); - return base64EncodedStr.replace(new RegExp(".{" + lineLengthMax + "}", "g"), "$&\r\n").trim(); - }, - - - /** - * Adds soft line breaks to a quoted printable string. - * - * @private - * @param {string} mimeEncodedStr - * @param {number} lineLengthMax - * @returns {string} - */ - _addQPSoftLinebreaks: function(mimeEncodedStr, lineLengthMax) { - let pos = 0, - len = mimeEncodedStr.length, - match, code, line, - lineMargin = Math.floor(lineLengthMax / 3), - result = ""; - - // insert soft linebreaks where needed - while (pos < len) { - line = mimeEncodedStr.substr(pos, lineLengthMax); - if ((match = line.match(/\r\n/))) { - line = line.substr(0, match.index + match[0].length); - result += line; - pos += line.length; - continue; - } - - if (line.substr(-1) === "\n") { - // nothing to change here - result += line; - pos += line.length; - continue; - } else if ((match = line.substr(-lineMargin).match(/\n.*?$/))) { - // truncate to nearest line break - line = line.substr(0, line.length - (match[0].length - 1)); - result += line; - pos += line.length; - continue; - } else if (line.length > lineLengthMax - lineMargin && (match = line.substr(-lineMargin).match(/[ \t.,!?][^ \t.,!?]*$/))) { - // truncate to nearest space - line = line.substr(0, line.length - (match[0].length - 1)); - } else if (line.substr(-1) === "\r") { - line = line.substr(0, line.length - 1); - } else { - if (line.match(/=[\da-f]{0,2}$/i)) { - - // push incomplete encoding sequences to the next line - if ((match = line.match(/=[\da-f]{0,1}$/i))) { - line = line.substr(0, line.length - match[0].length); - } - - // ensure that utf-8 sequences are not split - while (line.length > 3 && line.length < len - pos && !line.match(/^(?:=[\da-f]{2}){1,4}$/i) && (match = line.match(/=[\da-f]{2}$/ig))) { - code = parseInt(match[0].substr(1, 2), 16); - if (code < 128) { - break; - } - - line = line.substr(0, line.length - 3); - - if (code >= 0xC0) { - break; - } - } - - } - } - - if (pos + line.length < len && line.substr(-1) !== "\n") { - if (line.length === 76 && line.match(/=[\da-f]{2}$/i)) { - line = line.substr(0, line.length - 3); - } else if (line.length === 76) { - line = line.substr(0, line.length - 1); - } - pos += line.length; - line += "=\r\n"; - } else { - pos += line.length; - } - - result += line; - } - - return result; - }, - -}; - -export default QuotedPrintable; diff --git a/src/core/operations/legacy/Regex.js b/src/core/operations/legacy/Regex.js deleted file mode 100644 index a4f544ef..00000000 --- a/src/core/operations/legacy/Regex.js +++ /dev/null @@ -1,278 +0,0 @@ -import XRegExp from "xregexp"; -import Utils from "../Utils.js"; - - -/** - * Regex operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2018 - * @license Apache-2.0 - * - * @namespace - */ -const Regex = { - - /** - * @constant - * @default - */ - REGEX_PRE_POPULATE: [ - { - name: "User defined", - value: "" - }, - { - name: "IPv4 address", - value: "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?" - }, - { - name: "IPv6 address", - value: "((?=.*::)(?!.*::.+::)(::)?([\\dA-Fa-f]{1,4}:(:|\\b)|){5}|([\\dA-Fa-f]{1,4}:){6})((([\\dA-Fa-f]{1,4}((?!\\3)::|:\\b|(?![\\dA-Fa-f])))|(?!\\2\\3)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})" - }, - { - name: "Email address", - value: "\\b(\\w[-.\\w]*)@([-\\w]+(?:\\.[-\\w]+)*)\\.([A-Za-z]{2,4})\\b" - }, - { - name: "URL", - value: "([A-Za-z]+://)([-\\w]+(?:\\.\\w[-\\w]*)+)(:\\d+)?(/[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]*(?:[.!,?]+[^.!,?\"<>\\[\\]{}\\s\\x7F-\\xFF]+)*)?" - }, - { - name: "Domain", - value: "\\b((?=[a-z0-9-]{1,63}\\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,63}\\b" - }, - { - name: "Windows file path", - value: "([A-Za-z]):\\\\((?:[A-Za-z\\d][A-Za-z\\d\\- \\x27_\\(\\)~]{0,61}\\\\?)*[A-Za-z\\d][A-Za-z\\d\\- \\x27_\\(\\)]{0,61})(\\.[A-Za-z\\d]{1,6})?" - }, - { - name: "UNIX file path", - value: "(?:/[A-Za-z\\d.][A-Za-z\\d\\-.]{0,61})+" - }, - { - name: "MAC address", - value: "[A-Fa-f\\d]{2}(?:[:-][A-Fa-f\\d]{2}){5}" - }, - { - name: "Date (yyyy-mm-dd)", - value: "((?:19|20)\\d\\d)[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])" - }, - { - name: "Date (dd/mm/yyyy)", - value: "(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((?:19|20)\\d\\d)" - }, - { - name: "Date (mm/dd/yyyy)", - value: "(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.]((?:19|20)\\d\\d)" - }, - { - name: "Strings", - value: "[A-Za-z\\d/\\-:.,_$%\\x27\"()<>= !\\[\\]{}@]{4,}" - }, - ], - /** - * @constant - * @default - */ - OUTPUT_FORMAT: ["Highlight matches", "List matches", "List capture groups", "List matches with capture groups"], - /** - * @constant - * @default - */ - DISPLAY_TOTAL: false, - - /** - * Regular expression operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {html} - */ - runRegex: function(input, args) { - const userRegex = args[1], - i = args[2], - m = args[3], - s = args[4], - u = args[5], - a = args[6], - displayTotal = args[7], - outputFormat = args[8]; - let modifiers = "g"; - - if (i) modifiers += "i"; - if (m) modifiers += "m"; - if (s) modifiers += "s"; - if (u) modifiers += "u"; - if (a) modifiers += "A"; - - if (userRegex && userRegex !== "^" && userRegex !== "$") { - try { - const regex = new XRegExp(userRegex, modifiers); - - switch (outputFormat) { - case "Highlight matches": - return Regex._regexHighlight(input, regex, displayTotal); - case "List matches": - return Utils.escapeHtml(Regex._regexList(input, regex, displayTotal, true, false)); - case "List capture groups": - return Utils.escapeHtml(Regex._regexList(input, regex, displayTotal, false, true)); - case "List matches with capture groups": - return Utils.escapeHtml(Regex._regexList(input, regex, displayTotal, true, true)); - default: - return "Error: Invalid output format"; - } - } catch (err) { - return "Invalid regex. Details: " + err.message; - } - } else { - return Utils.escapeHtml(input); - } - }, - - - /** - * @constant - * @default - */ - SEARCH_TYPE: ["Regex", "Extended (\\n, \\t, \\x...)", "Simple string"], - /** - * @constant - * @default - */ - FIND_REPLACE_GLOBAL: true, - /** - * @constant - * @default - */ - FIND_REPLACE_CASE: false, - /** - * @constant - * @default - */ - FIND_REPLACE_MULTILINE: true, - - /** - * Find / Replace operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runFindReplace: function(input, args) { - let find = args[0].string, - type = args[0].option, - replace = args[1], - g = args[2], - i = args[3], - m = args[4], - modifiers = ""; - - if (g) modifiers += "g"; - if (i) modifiers += "i"; - if (m) modifiers += "m"; - - if (type === "Regex") { - find = new RegExp(find, modifiers); - return input.replace(find, replace); - } - - if (type.indexOf("Extended") === 0) { - find = Utils.parseEscapedChars(find); - } - - find = new RegExp(Utils.escapeRegex(find), modifiers); - - return input.replace(find, replace); - }, - - - /** - * Adds HTML highlights to matches within a string. - * - * @private - * @param {string} input - * @param {RegExp} regex - * @param {boolean} displayTotal - * @returns {string} - */ - _regexHighlight: function(input, regex, displayTotal) { - let output = "", - m, - hl = 1, - i = 0, - total = 0; - - while ((m = regex.exec(input))) { - // Moves pointer when an empty string is matched (prevents infinite loop) - if (m.index === regex.lastIndex) { - regex.lastIndex++; - } - - // Add up to match - output += Utils.escapeHtml(input.slice(i, m.index)); - - // Add match with highlighting - output += "" + Utils.escapeHtml(m[0]) + ""; - - // Switch highlight - hl = hl === 1 ? 2 : 1; - - i = regex.lastIndex; - total++; - } - - // Add all after final match - output += Utils.escapeHtml(input.slice(i, input.length)); - - if (displayTotal) - output = "Total found: " + total + "\n\n" + output; - - return output; - }, - - - /** - * Creates a string listing the matches within a string. - * - * @private - * @param {string} input - * @param {RegExp} regex - * @param {boolean} displayTotal - * @param {boolean} matches - Display full match - * @param {boolean} captureGroups - Display each of the capture groups separately - * @returns {string} - */ - _regexList: function(input, regex, displayTotal, matches, captureGroups) { - let output = "", - total = 0, - match; - - while ((match = regex.exec(input))) { - // Moves pointer when an empty string is matched (prevents infinite loop) - if (match.index === regex.lastIndex) { - regex.lastIndex++; - } - - total++; - if (matches) { - output += match[0] + "\n"; - } - if (captureGroups) { - for (let i = 1; i < match.length; i++) { - if (matches) { - output += " Group " + i + ": "; - } - output += match[i] + "\n"; - } - } - } - - if (displayTotal) - output = "Total found: " + total + "\n\n" + output; - - return output.slice(0, -1); - }, -}; - -export default Regex; diff --git a/src/core/operations/legacy/SeqUtils.js b/src/core/operations/legacy/SeqUtils.js deleted file mode 100755 index 4080528a..00000000 --- a/src/core/operations/legacy/SeqUtils.js +++ /dev/null @@ -1,257 +0,0 @@ -import Utils from "../Utils.js"; - - -/** - * Sequence utility operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const SeqUtils = { - - /** - * @constant - * @default - */ - DELIMITER_OPTIONS: ["Line feed", "CRLF", "Space", "Comma", "Semi-colon", "Colon", "Nothing (separate chars)"], - /** - * @constant - * @default - */ - SORT_REVERSE: false, - /** - * @constant - * @default - */ - SORT_ORDER: ["Alphabetical (case sensitive)", "Alphabetical (case insensitive)", "IP address", "Numeric"], - - /** - * Sort operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runSort: function (input, args) { - let delim = Utils.charRep(args[0]), - sortReverse = args[1], - order = args[2], - sorted = input.split(delim); - - if (order === "Alphabetical (case sensitive)") { - sorted = sorted.sort(); - } else if (order === "Alphabetical (case insensitive)") { - sorted = sorted.sort(SeqUtils._caseInsensitiveSort); - } else if (order === "IP address") { - sorted = sorted.sort(SeqUtils._ipSort); - } else if (order === "Numeric") { - sorted = sorted.sort(SeqUtils._numericSort); - } - - if (sortReverse) sorted.reverse(); - return sorted.join(delim); - }, - - - /** - * Unique operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runUnique: function (input, args) { - const delim = Utils.charRep(args[0]); - return input.split(delim).unique().join(delim); - }, - - - /** - * @constant - * @default - */ - SEARCH_TYPE: ["Regex", "Extended (\\n, \\t, \\x...)", "Simple string"], - - /** - * Count occurrences operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {number} - */ - runCount: function(input, args) { - let search = args[0].string, - type = args[0].option; - - if (type === "Regex" && search) { - try { - let regex = new RegExp(search, "gi"), - matches = input.match(regex); - return matches.length; - } catch (err) { - return 0; - } - } else if (search) { - if (type.indexOf("Extended") === 0) { - search = Utils.parseEscapedChars(search); - } - return input.count(search); - } else { - return 0; - } - }, - - - /** - * @constant - * @default - */ - REVERSE_BY: ["Character", "Line"], - - /** - * Reverse operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {byteArray} - */ - runReverse: function (input, args) { - let i; - if (args[0] === "Line") { - let lines = [], - line = [], - result = []; - for (i = 0; i < input.length; i++) { - if (input[i] === 0x0a) { - lines.push(line); - line = []; - } else { - line.push(input[i]); - } - } - lines.push(line); - lines.reverse(); - for (i = 0; i < lines.length; i++) { - result = result.concat(lines[i]); - result.push(0x0a); - } - return result.slice(0, input.length); - } else { - return input.reverse(); - } - }, - - - /** - * Add line numbers operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runAddLineNumbers: function(input, args) { - let lines = input.split("\n"), - output = "", - width = lines.length.toString().length; - - for (let n = 0; n < lines.length; n++) { - output += (n+1).toString().padStart(width, " ") + " " + lines[n] + "\n"; - } - return output.slice(0, output.length-1); - }, - - - /** - * Remove line numbers operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runRemoveLineNumbers: function(input, args) { - return input.replace(/^[ \t]{0,5}\d+[\s:|\-,.)\]]/gm, ""); - }, - - - /** - * Expand alphabet range operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runExpandAlphRange: function(input, args) { - return Utils.expandAlphRange(input).join(args[0]); - }, - - - /** - * Comparison operation for sorting of strings ignoring case. - * - * @private - * @param {string} a - * @param {string} b - * @returns {number} - */ - _caseInsensitiveSort: function(a, b) { - return a.toLowerCase().localeCompare(b.toLowerCase()); - }, - - - /** - * Comparison operation for sorting of IPv4 addresses. - * - * @private - * @param {string} a - * @param {string} b - * @returns {number} - */ - _ipSort: function(a, b) { - let a_ = a.split("."), - b_ = b.split("."); - - a_ = a_[0] * 0x1000000 + a_[1] * 0x10000 + a_[2] * 0x100 + a_[3] * 1; - b_ = b_[0] * 0x1000000 + b_[1] * 0x10000 + b_[2] * 0x100 + b_[3] * 1; - - if (isNaN(a_) && !isNaN(b_)) return 1; - if (!isNaN(a_) && isNaN(b_)) return -1; - if (isNaN(a_) && isNaN(b_)) return a.localeCompare(b); - - return a_ - b_; - }, - - - /** - * Comparison operation for sorting of numeric values. - * - * @author Chris van Marle - * @private - * @param {string} a - * @param {string} b - * @returns {number} - */ - _numericSort: function _numericSort(a, b) { - let a_ = a.split(/([^\d]+)/), - b_ = b.split(/([^\d]+)/); - - for (let i = 0; i < a_.length && i < b.length; ++i) { - if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers - if (!isNaN(a_[i]) && isNaN(b_[i])) return -1; - if (isNaN(a_[i]) && isNaN(b_[i])) { - let ret = a_[i].localeCompare(b_[i]); // Compare strings - if (ret !== 0) return ret; - } - if (!isNaN(a_[i]) && !isNaN(a_[i])) { // Compare numbers - if (a_[i] - b_[i] !== 0) return a_[i] - b_[i]; - } - } - - return a.localeCompare(b); - }, - -}; - -export default SeqUtils; diff --git a/src/core/operations/legacy/Shellcode.js b/src/core/operations/legacy/Shellcode.js deleted file mode 100644 index 920b12c6..00000000 --- a/src/core/operations/legacy/Shellcode.js +++ /dev/null @@ -1,96 +0,0 @@ -import disassemble from "../vendor/DisassembleX86-64.js"; - - -/** - * Shellcode operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2017 - * @license Apache-2.0 - * - * @namespace - */ -const Shellcode = { - - /** - * @constant - * @default - */ - MODE: ["64", "32", "16"], - /** - * @constant - * @default - */ - COMPATIBILITY: [ - "Full x86 architecture", - "Knights Corner", - "Larrabee", - "Cyrix", - "Geode", - "Centaur", - "X86/486" - ], - - /** - * Disassemble x86 operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runDisassemble: function(input, args) { - const mode = args[0], - compatibility = args[1], - codeSegment = args[2], - offset = args[3], - showInstructionHex = args[4], - showInstructionPos = args[5]; - - switch (mode) { - case "64": - disassemble.setBitMode(2); - break; - case "32": - disassemble.setBitMode(1); - break; - case "16": - disassemble.setBitMode(0); - break; - default: - throw "Invalid mode value"; - } - - switch (compatibility) { - case "Full x86 architecture": - disassemble.CompatibilityMode(0); - break; - case "Knights Corner": - disassemble.CompatibilityMode(1); - break; - case "Larrabee": - disassemble.CompatibilityMode(2); - break; - case "Cyrix": - disassemble.CompatibilityMode(3); - break; - case "Geode": - disassemble.CompatibilityMode(4); - break; - case "Centaur": - disassemble.CompatibilityMode(5); - break; - case "X86/486": - disassemble.CompatibilityMode(6); - break; - } - - disassemble.SetBasePosition(codeSegment + ":" + offset); - disassemble.setShowInstructionHex(showInstructionHex); - disassemble.setShowInstructionPos(showInstructionPos); - disassemble.LoadBinCode(input.replace(/\s/g, "")); - return disassemble.LDisassemble(); - }, - -}; - -export default Shellcode; diff --git a/src/core/operations/legacy/StrUtils.js b/src/core/operations/legacy/StrUtils.js deleted file mode 100755 index 9a5c010e..00000000 --- a/src/core/operations/legacy/StrUtils.js +++ /dev/null @@ -1,413 +0,0 @@ -import Utils from "../Utils.js"; -import {fromHex} from "../lib/Hex"; -import jsesc from "jsesc"; - - -/** - * String utility operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const StrUtils = { - - /** - * @constant - * @default - */ - CASE_SCOPE: ["All", "Word", "Sentence", "Paragraph"], - - /** - * To Upper case operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runUpper: function (input, args) { - const scope = args[0]; - - switch (scope) { - case "Word": - return input.replace(/(\b\w)/gi, function(m) { - return m.toUpperCase(); - }); - case "Sentence": - return input.replace(/(?:\.|^)\s*(\b\w)/gi, function(m) { - return m.toUpperCase(); - }); - case "Paragraph": - return input.replace(/(?:\n|^)\s*(\b\w)/gi, function(m) { - return m.toUpperCase(); - }); - case "All": - /* falls through */ - default: - return input.toUpperCase(); - } - }, - - - /** - * To Upper case operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runLower: function (input, args) { - return input.toLowerCase(); - }, - - - /** - * @constant - * @default - */ - SPLIT_DELIM_OPTIONS: [ - {name: "Comma", value: ","}, - {name: "Space", value: " "}, - {name: "Line feed", value: "\\n"}, - {name: "CRLF", value: "\\r\\n"}, - {name: "Semi-colon", value: ";"}, - {name: "Colon", value: ":"}, - {name: "Nothing (separate chars)", value: ""} - ], - /** - * @constant - * @default - */ - JOIN_DELIM_OPTIONS: [ - {name: "Line feed", value: "\\n"}, - {name: "CRLF", value: "\\r\\n"}, - {name: "Space", value: " "}, - {name: "Comma", value: ","}, - {name: "Semi-colon", value: ";"}, - {name: "Colon", value: ":"}, - {name: "Nothing (join chars)", value: ""} - ], - - /** - * Split operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runSplit: function(input, args) { - let splitDelim = args[0], - joinDelim = args[1], - sections = input.split(splitDelim); - - return sections.join(joinDelim); - }, - - - /** - * @constant - * @default - */ - DELIMITER_OPTIONS: ["Line feed", "CRLF", "Space", "Comma", "Semi-colon", "Colon", "Nothing (separate chars)"], - - /** - * Filter operation. - * - * @author Mikescher (https://github.com/Mikescher | https://mikescher.com) - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runFilter: function(input, args) { - let delim = Utils.charRep(args[0]), - regex, - reverse = args[2]; - - try { - regex = new RegExp(args[1]); - } catch (err) { - return "Invalid regex. Details: " + err.message; - } - - const regexFilter = function(value) { - return reverse ^ regex.test(value); - }; - - return input.split(delim).filter(regexFilter).join(delim); - }, - - - /** - * @constant - * @default - */ - OFF_CHK_SAMPLE_DELIMITER: "\\n\\n", - - /** - * Offset checker operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {html} - */ - runOffsetChecker: function(input, args) { - let sampleDelim = args[0], - samples = input.split(sampleDelim), - outputs = new Array(samples.length), - i = 0, - s = 0, - match = false, - inMatch = false, - chr; - - if (!samples || samples.length < 2) { - return "Not enough samples, perhaps you need to modify the sample delimiter or add more data?"; - } - - // Initialise output strings - outputs.fill("", 0, samples.length); - - // Loop through each character in the first sample - for (i = 0; i < samples[0].length; i++) { - chr = samples[0][i]; - match = false; - - // Loop through each sample to see if the chars are the same - for (s = 1; s < samples.length; s++) { - if (samples[s][i] !== chr) { - match = false; - break; - } - match = true; - } - - // Write output for each sample - for (s = 0; s < samples.length; s++) { - if (samples[s].length <= i) { - if (inMatch) outputs[s] += "
"; - if (s === samples.length - 1) inMatch = false; - continue; - } - - if (match && !inMatch) { - outputs[s] += "" + Utils.escapeHtml(samples[s][i]); - if (samples[s].length === i + 1) outputs[s] += ""; - if (s === samples.length - 1) inMatch = true; - } else if (!match && inMatch) { - outputs[s] += "
" + Utils.escapeHtml(samples[s][i]); - if (s === samples.length - 1) inMatch = false; - } else { - outputs[s] += Utils.escapeHtml(samples[s][i]); - if (inMatch && samples[s].length === i + 1) { - outputs[s] += ""; - if (samples[s].length - 1 !== i) inMatch = false; - } - } - - if (samples[0].length - 1 === i) { - if (inMatch) outputs[s] += ""; - outputs[s] += Utils.escapeHtml(samples[s].substring(i + 1)); - } - } - } - - return outputs.join(sampleDelim); - }, - - - /** - * @constant - * @default - */ - QUOTE_TYPES: ["Single", "Double", "Backtick"], - /** - * @constant - * @default - */ - ESCAPE_LEVEL: ["Special chars", "Everything", "Minimal"], - - /** - * Escape string operation. - * - * @author Vel0x [dalemy@microsoft.com] - * @author n1474335 [n1474335@gmail.com] - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - * - * @example - * StrUtils.runEscape("Don't do that", []) - * > "Don\'t do that" - * StrUtils.runEscape(`Hello - * World`, []) - * > "Hello\nWorld" - */ - runEscape: function(input, args) { - const level = args[0], - quotes = args[1], - jsonCompat = args[2], - es6Compat = args[3], - lowercaseHex = !args[4]; - - return jsesc(input, { - quotes: quotes.toLowerCase(), - es6: es6Compat, - escapeEverything: level === "Everything", - minimal: level === "Minimal", - json: jsonCompat, - lowercaseHex: lowercaseHex, - }); - }, - - - /** - * Unescape string operation. - * - * @author Vel0x [dalemy@microsoft.com] - * @author n1474335 [n1474335@gmail.com] - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - * - * @example - * StrUtils.runUnescape("Don\'t do that", []) - * > "Don't do that" - * StrUtils.runUnescape("Hello\nWorld", []) - * > `Hello - * World` - */ - runUnescape: function(input, args) { - return Utils.parseEscapedChars(input); - }, - - - /** - * Head lines operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runHead: function(input, args) { - let delimiter = args[0], - number = args[1]; - - delimiter = Utils.charRep(delimiter); - const splitInput = input.split(delimiter); - - return splitInput - .filter((line, lineIndex) => { - lineIndex += 1; - - if (number < 0) { - return lineIndex <= splitInput.length + number; - } else { - return lineIndex <= number; - } - }) - .join(delimiter); - }, - - - /** - * Tail lines operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runTail: function(input, args) { - let delimiter = args[0], - number = args[1]; - - delimiter = Utils.charRep(delimiter); - const splitInput = input.split(delimiter); - - return splitInput - .filter((line, lineIndex) => { - lineIndex += 1; - - if (number < 0) { - return lineIndex > -number; - } else { - return lineIndex > splitInput.length - number; - } - }) - .join(delimiter); - }, - - - /** - * @constant - * @default - */ - HAMMING_DELIM: "\\n\\n", - /** - * @constant - * @default - */ - HAMMING_INPUT_TYPE: ["Raw string", "Hex"], - /** - * @constant - * @default - */ - HAMMING_UNIT: ["Byte", "Bit"], - - /** - * Hamming Distance operation. - * - * @author GCHQ Contributor [2] - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runHamming: function(input, args) { - const delim = args[0], - byByte = args[1] === "Byte", - inputType = args[2], - samples = input.split(delim); - - if (samples.length !== 2) { - return "Error: You can only calculae the edit distance between 2 strings. Please ensure exactly two inputs are provided, separated by the specified delimiter."; - } - - if (samples[0].length !== samples[1].length) { - return "Error: Both inputs must be of the same length."; - } - - if (inputType === "Hex") { - samples[0] = fromHex(samples[0]); - samples[1] = fromHex(samples[1]); - } else { - samples[0] = Utils.strToByteArray(samples[0]); - samples[1] = Utils.strToByteArray(samples[1]); - } - - let dist = 0; - - for (let i = 0; i < samples[0].length; i++) { - const lhs = samples[0][i], - rhs = samples[1][i]; - - if (byByte && lhs !== rhs) { - dist++; - } else if (!byByte) { - let xord = lhs ^ rhs; - - while (xord) { - dist++; - xord &= xord - 1; - } - } - } - - return dist.toString(); - }, -}; - -export default StrUtils; diff --git a/src/core/operations/legacy/Tidy.js b/src/core/operations/legacy/Tidy.js deleted file mode 100755 index 175d888e..00000000 --- a/src/core/operations/legacy/Tidy.js +++ /dev/null @@ -1,250 +0,0 @@ -/** - * Tidy operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Tidy = { - - /** - * @constant - * @default - */ - REMOVE_SPACES: true, - /** - * @constant - * @default - */ - REMOVE_CARIAGE_RETURNS: true, - /** - * @constant - * @default - */ - REMOVE_LINE_FEEDS: true, - /** - * @constant - * @default - */ - REMOVE_TABS: true, - /** - * @constant - * @default - */ - REMOVE_FORM_FEEDS: true, - /** - * @constant - * @default - */ - REMOVE_FULL_STOPS: false, - - /** - * Remove whitespace operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runRemoveWhitespace: function (input, args) { - let removeSpaces = args[0], - removeCariageReturns = args[1], - removeLineFeeds = args[2], - removeTabs = args[3], - removeFormFeeds = args[4], - removeFullStops = args[5], - data = input; - - if (removeSpaces) data = data.replace(/ /g, ""); - if (removeCariageReturns) data = data.replace(/\r/g, ""); - if (removeLineFeeds) data = data.replace(/\n/g, ""); - if (removeTabs) data = data.replace(/\t/g, ""); - if (removeFormFeeds) data = data.replace(/\f/g, ""); - if (removeFullStops) data = data.replace(/\./g, ""); - return data; - }, - - - /** - * Remove null bytes operation. - * - * @param {byteArray} input - * @param {Object[]} args - * @returns {byteArray} - */ - runRemoveNulls: function (input, args) { - const output = []; - for (let i = 0; i < input.length; i++) { - if (input[i] !== 0) output.push(input[i]); - } - return output; - }, - - - /** - * @constant - * @default - */ - APPLY_TO_EACH_LINE: false, - /** - * @constant - * @default - */ - DROP_START: 0, - /** - * @constant - * @default - */ - DROP_LENGTH: 5, - - /** - * Drop bytes operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {ArrayBuffer} - */ - runDropBytes: function(input, args) { - const start = args[0], - length = args[1], - applyToEachLine = args[2]; - - if (start < 0 || length < 0) - throw "Error: Invalid value"; - - if (!applyToEachLine) { - const left = input.slice(0, start), - right = input.slice(start + length, input.byteLength); - let result = new Uint8Array(left.byteLength + right.byteLength); - result.set(new Uint8Array(left), 0); - result.set(new Uint8Array(right), left.byteLength); - return result.buffer; - } - - // Split input into lines - const data = new Uint8Array(input); - let lines = [], - line = [], - i; - - for (i = 0; i < data.length; i++) { - if (data[i] === 0x0a) { - lines.push(line); - line = []; - } else { - line.push(data[i]); - } - } - lines.push(line); - - let output = []; - for (i = 0; i < lines.length; i++) { - output = output.concat(lines[i].slice(0, start).concat(lines[i].slice(start+length, lines[i].length))); - output.push(0x0a); - } - return new Uint8Array(output.slice(0, output.length-1)).buffer; - }, - - - /** - * @constant - * @default - */ - TAKE_START: 0, - /** - * @constant - * @default - */ - TAKE_LENGTH: 5, - - /** - * Take bytes operation. - * - * @param {ArrayBuffer} input - * @param {Object[]} args - * @returns {ArrayBuffer} - */ - runTakeBytes: function(input, args) { - const start = args[0], - length = args[1], - applyToEachLine = args[2]; - - if (start < 0 || length < 0) - throw "Error: Invalid value"; - - if (!applyToEachLine) - return input.slice(start, start+length); - - // Split input into lines - const data = new Uint8Array(input); - let lines = [], - line = [], - i; - - for (i = 0; i < data.length; i++) { - if (data[i] === 0x0a) { - lines.push(line); - line = []; - } else { - line.push(data[i]); - } - } - lines.push(line); - - let output = []; - for (i = 0; i < lines.length; i++) { - output = output.concat(lines[i].slice(start, start+length)); - output.push(0x0a); - } - return new Uint8Array(output.slice(0, output.length-1)).buffer; - }, - - - /** - * @constant - * @default - */ - PAD_POSITION: ["Start", "End"], - /** - * @constant - * @default - */ - PAD_LENGTH: 5, - /** - * @constant - * @default - */ - PAD_CHAR: " ", - - /** - * Pad lines operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runPad: function(input, args) { - let position = args[0], - len = args[1], - chr = args[2], - lines = input.split("\n"), - output = "", - i = 0; - - if (position === "Start") { - for (i = 0; i < lines.length; i++) { - output += lines[i].padStart(lines[i].length+len, chr) + "\n"; - } - } else if (position === "End") { - for (i = 0; i < lines.length; i++) { - output += lines[i].padEnd(lines[i].length+len, chr) + "\n"; - } - } - - return output.slice(0, output.length-1); - }, - -}; - -export default Tidy; diff --git a/src/core/operations/legacy/ToTable.js b/src/core/operations/legacy/ToTable.js deleted file mode 100644 index b18b56f1..00000000 --- a/src/core/operations/legacy/ToTable.js +++ /dev/null @@ -1,164 +0,0 @@ -/** - * ToTable operations. - * - * @author Mark Jones [github.com/justanothermark] - * @copyright Crown Copyright 2018 - * @license Apache-2.0 - * - * @namespace - */ -import Utils from "../Utils.js"; - -const ToTable = { - - /** - * @constant - * @default - */ - FORMATS: [ - "ASCII", - "HTML" - ], - - - /** - * To Table operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {html} - */ - runToTable: function (input, args) { - const [cellDelims, rowDelims, firstRowHeader, format] = args; - - // Process the input into a nested array of elements. - const tableData = Utils.parseCSV(input, cellDelims.split(""), rowDelims.split("")); - - if (!tableData.length) return ""; - - // Render the data in the requested format. - switch (format) { - case "ASCII": - return asciiOutput(tableData); - case "HTML": - default: - return htmlOutput(tableData); - } - - /** - * Outputs an array of data as an ASCII table. - * - * @param {string[][]} tableData - * @returns {string} - */ - function asciiOutput(tableData) { - const horizontalBorder = "-"; - const verticalBorder = "|"; - const crossBorder = "+"; - - let output = ""; - let longestCells = []; - - // Find longestCells value per column to pad cells equally. - tableData.forEach(function(row, index) { - row.forEach(function(cell, cellIndex) { - if (longestCells[cellIndex] === undefined || cell.length > longestCells[cellIndex]) { - longestCells[cellIndex] = cell.length; - } - }); - }); - - // Add the top border of the table to the output. - output += outputHorizontalBorder(longestCells); - - // If the first row is a header, remove the row from the data and - // add it to the output with another horizontal border. - if (firstRowHeader) { - let row = tableData.shift(); - output += outputRow(row, longestCells); - output += outputHorizontalBorder(longestCells); - } - - // Add the rest of the table rows. - tableData.forEach(function(row, index) { - output += outputRow(row, longestCells); - }); - - // Close the table with a final horizontal border. - output += outputHorizontalBorder(longestCells); - - return output; - - /** - * Outputs a row of correctly padded cells. - */ - function outputRow(row, longestCells) { - let rowOutput = verticalBorder; - row.forEach(function(cell, index) { - rowOutput += " " + cell + " ".repeat(longestCells[index] - cell.length) + " " + verticalBorder; - }); - rowOutput += "\n"; - return rowOutput; - } - - /** - * Outputs a horizontal border with a different character where - * the horizontal border meets a vertical border. - */ - function outputHorizontalBorder(longestCells) { - let rowOutput = crossBorder; - longestCells.forEach(function(cellLength) { - rowOutput += horizontalBorder.repeat(cellLength + 2) + crossBorder; - }); - rowOutput += "\n"; - return rowOutput; - } - } - - /** - * Outputs a table of data as a HTML table. - * - * @param {string[][]} tableData - * @returns {string} - */ - function htmlOutput(tableData) { - // Start the HTML output with suitable classes for styling. - let output = ""; - - // If the first row is a header then put it in with "; - output += outputRow(row, "th"); - output += ""; - } - - // Output the rest of the rows in the . - output += ""; - tableData.forEach(function(row, index) { - output += outputRow(row, "td"); - }); - - // Close the body and table elements. - output += "
cells. - if (firstRowHeader) { - let row = tableData.shift(); - output += "
"; - return output; - - /** - * Outputs a table row. - * - * @param {string[]} row - * @param {string} cellType - */ - function outputRow(row, cellType) { - let output = ""; - row.forEach(function(cell) { - output += "<" + cellType + ">" + cell + ""; - }); - output += ""; - return output; - } - } - } -}; - -export default ToTable; diff --git a/src/core/operations/legacy/UUID.js b/src/core/operations/legacy/UUID.js deleted file mode 100755 index 7b485579..00000000 --- a/src/core/operations/legacy/UUID.js +++ /dev/null @@ -1,36 +0,0 @@ -import crypto from "crypto"; - - -/** - * UUID operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const UUID = { - - /** - * Generate UUID operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runGenerateV4: function(input, args) { - const buf = new Uint32Array(4).map(() => { - return crypto.randomBytes(4).readUInt32BE(0, true); - }); - let i = 0; - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { - let r = (buf[i >> 3] >> ((i % 8) * 4)) & 0xf, - v = c === "x" ? r : (r & 0x3 | 0x8); - i++; - return v.toString(16); - }); - } -}; - -export default UUID; diff --git a/src/core/operations/legacy/Unicode.js b/src/core/operations/legacy/Unicode.js deleted file mode 100755 index 104ef07e..00000000 --- a/src/core/operations/legacy/Unicode.js +++ /dev/null @@ -1,101 +0,0 @@ -import Utils from "../Utils.js"; - - -/** - * Unicode operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - * - * @namespace - */ -const Unicode = { - - /** - * @constant - * @default - */ - PREFIXES: ["\\u", "%u", "U+"], - - /** - * Unescape Unicode Characters operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runUnescape: function(input, args) { - let prefix = Unicode._prefixToRegex[args[0]], - regex = new RegExp(prefix+"([a-f\\d]{4})", "ig"), - output = "", - m, - i = 0; - - while ((m = regex.exec(input))) { - // Add up to match - output += input.slice(i, m.index); - i = m.index; - - // Add match - output += Utils.chr(parseInt(m[1], 16)); - - i = regex.lastIndex; - } - - // Add all after final match - output += input.slice(i, input.length); - - return output; - }, - - - /** - * Escape Unicode Characters operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {string} - */ - runEscape: function(input, args) { - const regexWhitelist = /[ -~]/i, - prefix = args[0], - encodeAll = args[1], - padding = args[2], - uppercaseHex = args[3]; - - let output = "", - character = ""; - - for (let i = 0; i < input.length; i++) { - character = input[i]; - if (!encodeAll && regexWhitelist.test(character)) { - // It’s a printable ASCII character so don’t escape it. - output += character; - continue; - } - - let cp = character.codePointAt(0).toString(16); - if (uppercaseHex) cp = cp.toUpperCase(); - output += prefix + cp.padStart(padding, "0"); - } - - return output; - }, - - - /** - * Lookup table to add prefixes to unicode delimiters so that they can be used in a regex. - * - * @private - * @constant - */ - _prefixToRegex: { - "\\u": "\\\\u", - "%u": "%u", - "U+": "U\\+" - }, - -}; - -export default Unicode; diff --git a/src/core/operations/legacy/XKCD.js b/src/core/operations/legacy/XKCD.js deleted file mode 100755 index 4144d88f..00000000 --- a/src/core/operations/legacy/XKCD.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * XKCD operations. - * - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2018 - * @license Apache-2.0 - * - * @namespace - */ -const XKCD = { - - /** - * XKCD Random Number operation. - * - * @param {string} input - * @param {Object[]} args - * @returns {number} - */ - runRandomNumber: function(input, args) { - return 4; // chosen by fair dice roll. - // guaranteed to be random. - }, - -}; - -export default XKCD; diff --git a/src/web/App.js b/src/web/App.js deleted file mode 100644 index c08658a7..00000000 --- a/src/web/App.js +++ /dev/null @@ -1,753 +0,0 @@ -/** - * @author n1474335 [n1474335@gmail.com] - * @copyright Crown Copyright 2016 - * @license Apache-2.0 - */ - -import Utils from "../core/Utils"; -import {fromBase64} from "../core/lib/Base64"; -import Manager from "./Manager"; -import HTMLCategory from "./HTMLCategory"; -import HTMLOperation from "./HTMLOperation"; -import Split from "split.js"; - - -/** - * HTML view for CyberChef responsible for building the web page and dealing with all user - * interactions. - */ -class App { - - /** - * App constructor. - * - * @param {CatConf[]} categories - The list of categories and operations to be populated. - * @param {Object.} operations - The list of operation configuration objects. - * @param {String[]} defaultFavourites - A list of default favourite operations. - * @param {Object} options - Default setting for app options. - */ - constructor(categories, operations, defaultFavourites, defaultOptions) { - this.categories = categories; - this.operations = operations; - this.dfavourites = defaultFavourites; - this.doptions = defaultOptions; - this.options = Object.assign({}, defaultOptions); - - this.manager = new Manager(this); - - this.baking = false; - this.autoBake_ = false; - this.autoBakePause = false; - this.progress = 0; - this.ingId = 0; - } - - - /** - * This function sets up the stage and creates listeners for all events. - * - * @fires Manager#appstart - */ - setup() { - document.dispatchEvent(this.manager.appstart); - this.initialiseSplitter(); - this.loadLocalStorage(); - this.populateOperationsList(); - this.manager.setup(); - this.resetLayout(); - this.setCompileMessage(); - - log.debug("App loaded"); - this.appLoaded = true; - - this.loadURIParams(); - this.loaded(); - } - - - /** - * Fires once all setup activities have completed. - * - * @fires Manager#apploaded - */ - loaded() { - // Check that both the app and the worker have loaded successfully, and that - // we haven't already loaded before attempting to remove the loading screen. - if (!this.workerLoaded || !this.appLoaded || - !document.getElementById("loader-wrapper")) return; - - // Trigger CSS animations to remove preloader - document.body.classList.add("loaded"); - - // Wait for animations to complete then remove the preloader and loaded style - // so that the animations for existing elements don't play again. - setTimeout(function() { - document.getElementById("loader-wrapper").remove(); - document.body.classList.remove("loaded"); - }, 1000); - - // Clear the loading message interval - clearInterval(window.loadingMsgsInt); - - // Remove the loading error handler - window.removeEventListener("error", window.loadingErrorHandler); - - document.dispatchEvent(this.manager.apploaded); - } - - - /** - * An error handler for displaying the error to the user. - * - * @param {Error} err - * @param {boolean} [logToConsole=false] - */ - handleError(err, logToConsole) { - if (logToConsole) log.error(err); - const msg = err.displayStr || err.toString(); - this.alert(msg, "danger", this.options.errorTimeout, !this.options.showErrors); - } - - - /** - * Asks the ChefWorker to bake the current input using the current recipe. - * - * @param {boolean} [step] - Set to true if we should only execute one operation instead of the - * whole recipe. - */ - bake(step) { - if (this.baking) return; - - // Reset attemptHighlight flag - this.options.attemptHighlight = true; - - this.manager.worker.bake( - this.getInput(), // The user's input - this.getRecipeConfig(), // The configuration of the recipe - this.options, // Options set by the user - this.progress, // The current position in the recipe - step // Whether or not to take one step or execute the whole recipe - ); - } - - - /** - * Runs Auto Bake if it is set. - */ - autoBake() { - // If autoBakePause is set, we are loading a full recipe (and potentially input), so there is no - // need to set the staleness indicator. Just exit and wait until auto bake is called after loading - // has completed. - if (this.autoBakePause) return false; - - if (this.autoBake_ && !this.baking) { - log.debug("Auto-baking"); - this.bake(); - } else { - this.manager.controls.showStaleIndicator(); - } - } - - - /** - * Runs a silent bake, forcing the browser to load and cache all the relevant JavaScript code needed - * to do a real bake. - * - * The output will not be modified (hence "silent" bake). This will only actually execute the recipe - * if auto-bake is enabled, otherwise it will just wake up the ChefWorker with an empty recipe. - */ - silentBake() { - let recipeConfig = []; - - if (this.autoBake_) { - // If auto-bake is not enabled we don't want to actually run the recipe as it may be disabled - // for a good reason. - recipeConfig = this.getRecipeConfig(); - } - - this.manager.worker.silentBake(recipeConfig); - } - - - /** - * Gets the user's input data. - * - * @returns {string} - */ - getInput() { - return this.manager.input.get(); - } - - - /** - * Sets the user's input data. - * - * @param {string} input - The string to set the input to - */ - setInput(input) { - this.manager.input.set(input); - } - - - /** - * Populates the operations accordion list with the categories and operations specified in the - * view constructor. - * - * @fires Manager#oplistcreate - */ - populateOperationsList() { - // Move edit button away before we overwrite it - document.body.appendChild(document.getElementById("edit-favourites")); - - let html = ""; - let i; - - for (i = 0; i < this.categories.length; i++) { - const catConf = this.categories[i], - selected = i === 0, - cat = new HTMLCategory(catConf.name, selected); - - for (let j = 0; j < catConf.ops.length; j++) { - const opName = catConf.ops[j]; - if (!this.operations.hasOwnProperty(opName)) { - log.warn(`${opName} could not be found.`); - continue; - } - - const op = new HTMLOperation(opName, this.operations[opName], this, this.manager); - cat.addOperation(op); - } - - html += cat.toHtml(); - } - - document.getElementById("categories").innerHTML = html; - - const opLists = document.querySelectorAll("#categories .op-list"); - - for (i = 0; i < opLists.length; i++) { - opLists[i].dispatchEvent(this.manager.oplistcreate); - } - - // Add edit button to first category (Favourites) - document.querySelector("#categories a").appendChild(document.getElementById("edit-favourites")); - } - - - /** - * Sets up the adjustable splitter to allow the user to resize areas of the page. - */ - initialiseSplitter() { - this.columnSplitter = Split(["#operations", "#recipe", "#IO"], { - sizes: [20, 30, 50], - minSize: [240, 325, 450], - gutterSize: 4, - onDrag: function() { - this.manager.controls.adjustWidth(); - this.manager.output.adjustWidth(); - }.bind(this) - }); - - this.ioSplitter = Split(["#input", "#output"], { - direction: "vertical", - gutterSize: 4, - }); - - this.resetLayout(); - } - - - /** - * Loads the information previously saved to the HTML5 local storage object so that user options - * and favourites can be restored. - */ - loadLocalStorage() { - // Load options - let lOptions; - if (this.isLocalStorageAvailable() && localStorage.options !== undefined) { - lOptions = JSON.parse(localStorage.options); - } - this.manager.options.load(lOptions); - - // Load favourites - this.loadFavourites(); - } - - - /** - * Loads the user's favourite operations from the HTML5 local storage object and populates the - * Favourites category with them. - * If the user currently has no saved favourites, the defaults from the view constructor are used. - */ - loadFavourites() { - let favourites; - - if (this.isLocalStorageAvailable()) { - favourites = localStorage.favourites && localStorage.favourites.length > 2 ? - JSON.parse(localStorage.favourites) : - this.dfavourites; - favourites = this.validFavourites(favourites); - this.saveFavourites(favourites); - } else { - favourites = this.dfavourites; - } - - const favCat = this.categories.filter(function(c) { - return c.name === "Favourites"; - })[0]; - - if (favCat) { - favCat.ops = favourites; - } else { - this.categories.unshift({ - name: "Favourites", - ops: favourites - }); - } - } - - - /** - * Filters the list of favourite operations that the user had stored and removes any that are no - * longer available. The user is notified if this is the case. - - * @param {string[]} favourites - A list of the user's favourite operations - * @returns {string[]} A list of the valid favourites - */ - validFavourites(favourites) { - const validFavs = []; - for (let i = 0; i < favourites.length; i++) { - if (this.operations.hasOwnProperty(favourites[i])) { - validFavs.push(favourites[i]); - } else { - this.alert("The operation \"" + Utils.escapeHtml(favourites[i]) + - "\" is no longer available. It has been removed from your favourites.", "info"); - } - } - return validFavs; - } - - - /** - * Saves a list of favourite operations to the HTML5 local storage object. - * - * @param {string[]} favourites - A list of the user's favourite operations - */ - saveFavourites(favourites) { - if (!this.isLocalStorageAvailable()) { - this.alert( - "Your security settings do not allow access to local storage so your favourites cannot be saved.", - "danger", - 5000 - ); - return false; - } - - localStorage.setItem("favourites", JSON.stringify(this.validFavourites(favourites))); - } - - - /** - * Resets favourite operations back to the default as specified in the view constructor and - * refreshes the operation list. - */ - resetFavourites() { - this.saveFavourites(this.dfavourites); - this.loadFavourites(); - this.populateOperationsList(); - this.manager.recipe.initialiseOperationDragNDrop(); - } - - - /** - * Adds an operation to the user's favourites. - * - * @param {string} name - The name of the operation - */ - addFavourite(name) { - const favourites = JSON.parse(localStorage.favourites); - - if (favourites.indexOf(name) >= 0) { - this.alert("'" + name + "' is already in your favourites", "info", 2000); - return; - } - - favourites.push(name); - this.saveFavourites(favourites); - this.loadFavourites(); - this.populateOperationsList(); - this.manager.recipe.initialiseOperationDragNDrop(); - } - - - /** - * Checks for input and recipe in the URI parameters and loads them if present. - */ - loadURIParams() { - // Load query string or hash from URI (depending on which is populated) - // We prefer getting the hash by splitting the href rather than referencing - // location.hash as some browsers (Firefox) automatically URL decode it, - // which cause issues. - const params = window.location.search || - window.location.href.split("#")[1] || - window.location.hash; - this.uriParams = Utils.parseURIParams(params); - this.autoBakePause = true; - - // Read in recipe from URI params - if (this.uriParams.recipe) { - try { - const recipeConfig = Utils.parseRecipeConfig(this.uriParams.recipe); - this.setRecipeConfig(recipeConfig); - } catch (err) {} - } else if (this.uriParams.op) { - // If there's no recipe, look for single operations - this.manager.recipe.clearRecipe(); - - // Search for nearest match and add it - const matchedOps = this.manager.ops.filterOperations(this.uriParams.op, false); - if (matchedOps.length) { - this.manager.recipe.addOperation(matchedOps[0].name); - } - - // Populate search with the string - const search = document.getElementById("search"); - - search.value = this.uriParams.op; - search.dispatchEvent(new Event("search")); - } - - // Read in input data from URI params - if (this.uriParams.input) { - try { - const inputData = fromBase64(this.uriParams.input); - this.setInput(inputData); - } catch (err) {} - } - - this.autoBakePause = false; - this.autoBake(); - } - - - /** - * Returns the next ingredient ID and increments it for next time. - * - * @returns {number} - */ - nextIngId() { - return this.ingId++; - } - - - /** - * Gets the current recipe configuration. - * - * @returns {Object[]} - */ - getRecipeConfig() { - return this.manager.recipe.getConfig(); - } - - - /** - * Given a recipe configuration, sets the recipe to that configuration. - * - * @fires Manager#statechange - * @param {Object[]} recipeConfig - The recipe configuration - */ - setRecipeConfig(recipeConfig) { - document.getElementById("rec-list").innerHTML = null; - - // Pause auto-bake while loading but don't modify `this.autoBake_` - // otherwise `manualBake` cannot trigger. - this.autoBakePause = true; - - for (let i = 0; i < recipeConfig.length; i++) { - const item = this.manager.recipe.addOperation(recipeConfig[i].op); - - // Populate arguments - const args = item.querySelectorAll(".arg"); - for (let j = 0; j < args.length; j++) { - if (recipeConfig[i].args[j] === undefined) continue; - if (args[j].getAttribute("type") === "checkbox") { - // checkbox - args[j].checked = recipeConfig[i].args[j]; - } else if (args[j].classList.contains("toggle-string")) { - // toggleString - args[j].value = recipeConfig[i].args[j].string; - args[j].previousSibling.children[0].innerHTML = - Utils.escapeHtml(recipeConfig[i].args[j].option) + - " "; - } else { - // all others - args[j].value = recipeConfig[i].args[j]; - } - } - - // Set disabled and breakpoint - if (recipeConfig[i].disabled) { - item.querySelector(".disable-icon").click(); - } - if (recipeConfig[i].breakpoint) { - item.querySelector(".breakpoint").click(); - } - - this.progress = 0; - } - - // Unpause auto bake - this.autoBakePause = false; - } - - - /** - * Resets the splitter positions to default. - */ - resetLayout() { - this.columnSplitter.setSizes([20, 30, 50]); - this.ioSplitter.setSizes([50, 50]); - - this.manager.controls.adjustWidth(); - this.manager.output.adjustWidth(); - } - - - /** - * Sets the compile message. - */ - setCompileMessage() { - // Display time since last build and compile message - const now = new Date(), - timeSinceCompile = Utils.fuzzyTime(now.getTime() - window.compileTime); - - // Calculate previous version to compare to - const prev = PKG_VERSION.split(".").map(n => { - return parseInt(n, 10); - }); - if (prev[2] > 0) prev[2]--; - else if (prev[1] > 0) prev[1]--; - else prev[0]--; - - const compareURL = `https://github.com/gchq/CyberChef/compare/v${prev.join(".")}...v${PKG_VERSION}`; - - let compileInfo = `Last build: ${timeSinceCompile.substr(0, 1).toUpperCase() + timeSinceCompile.substr(1)} ago`; - - if (window.compileMessage !== "") { - compileInfo += " - " + window.compileMessage; - } - - document.getElementById("notice").innerHTML = compileInfo; - } - - - /** - * Determines whether the browser supports Local Storage and if it is accessible. - * - * @returns {boolean} - */ - isLocalStorageAvailable() { - try { - if (!localStorage) return false; - return true; - } catch (err) { - // Access to LocalStorage is denied - return false; - } - } - - - /** - * Pops up a message to the user and writes it to the console log. - * - * @param {string} str - The message to display (HTML supported) - * @param {string} style - The colour of the popup - * "danger" = red - * "warning" = amber - * "info" = blue - * "success" = green - * @param {number} timeout - The number of milliseconds before the popup closes automatically - * 0 for never (until the user closes it) - * @param {boolean} [silent=false] - Don't show the message in the popup, only print it to the - * console - * - * @example - * // Pops up a red box with the message "[current time] Error: Something has gone wrong!" - * // that will need to be dismissed by the user. - * this.alert("Error: Something has gone wrong!", "danger", 0); - * - * // Pops up a blue information box with the message "[current time] Happy Christmas!" - * // that will disappear after 5 seconds. - * this.alert("Happy Christmas!", "info", 5000); - */ - alert(str, style, timeout, silent) { - const time = new Date(); - - log.info("[" + time.toLocaleString() + "] " + str); - if (silent) return; - - style = style || "danger"; - timeout = timeout || 0; - - const alertEl = document.getElementById("alert"), - alertContent = document.getElementById("alert-content"); - - alertEl.classList.remove("alert-danger"); - alertEl.classList.remove("alert-warning"); - alertEl.classList.remove("alert-info"); - alertEl.classList.remove("alert-success"); - alertEl.classList.add("alert-" + style); - - // If the box hasn't been closed, append to it rather than replacing - if (alertEl.style.display === "block") { - alertContent.innerHTML += - "

[" + time.toLocaleTimeString() + "] " + str; - } else { - alertContent.innerHTML = - "[" + time.toLocaleTimeString() + "] " + str; - } - - // Stop the animation if it is in progress - $("#alert").stop(); - alertEl.style.display = "block"; - alertEl.style.opacity = 1; - - if (timeout > 0) { - clearTimeout(this.alertTimeout); - this.alertTimeout = setTimeout(function(){ - $("#alert").slideUp(100); - }, timeout); - } - } - - - /** - * Pops up a box asking the user a question and sending the answer to a specified callback function. - * - * @param {string} title - The title of the box - * @param {string} body - The question (HTML supported) - * @param {function} callback - A function accepting one boolean argument which handles the - * response e.g. function(answer) {...} - * @param {Object} [scope=this] - The object to bind to the callback function - * - * @example - * // Pops up a box asking if the user would like a cookie. Prints the answer to the console. - * this.confirm("Question", "Would you like a cookie?", function(answer) {console.log(answer);}); - */ - confirm(title, body, callback, scope) { - scope = scope || this; - document.getElementById("confirm-title").innerHTML = title; - document.getElementById("confirm-body").innerHTML = body; - document.getElementById("confirm-modal").style.display = "block"; - - this.confirmClosed = false; - $("#confirm-modal").modal() - .one("show.bs.modal", function(e) { - this.confirmClosed = false; - }.bind(this)) - .one("click", "#confirm-yes", function() { - this.confirmClosed = true; - callback.bind(scope)(true); - $("#confirm-modal").modal("hide"); - }.bind(this)) - .one("hide.bs.modal", function(e) { - if (!this.confirmClosed) - callback.bind(scope)(false); - this.confirmClosed = true; - }.bind(this)); - } - - - /** - * Handler for the alert close button click event. - * Closes the alert box. - */ - alertCloseClick() { - document.getElementById("alert").style.display = "none"; - } - - - /** - * Handler for CyerChef statechange events. - * Fires whenever the input or recipe changes in any way. - * - * @listens Manager#statechange - * @param {event} e - */ - stateChange(e) { - this.autoBake(); - - // Set title - const recipeConfig = this.getRecipeConfig(); - let title = "CyberChef"; - if (recipeConfig.length === 1) { - title = `${recipeConfig[0].op} - ${title}`; - } else if (recipeConfig.length > 1) { - // See how long the full recipe is - const ops = recipeConfig.map(op => op.op).join(", "); - if (ops.length < 45) { - title = `${ops} - ${title}`; - } else { - // If it's too long, just use the first one and say how many more there are - title = `${recipeConfig[0].op}, ${recipeConfig.length - 1} more - ${title}`; - } - } - document.title = title; - - // Update the current history state (not creating a new one) - if (this.options.updateUrl) { - this.lastStateUrl = this.manager.controls.generateStateUrl(true, true, recipeConfig); - window.history.replaceState({}, title, this.lastStateUrl); - } - } - - - /** - * Handler for the history popstate event. - * Reloads parameters from the URL. - * - * @param {event} e - */ - popState(e) { - this.loadURIParams(); - } - - - /** - * Function to call an external API from this view. - */ - callApi(url, type, data, dataType, contentType) { - type = type || "POST"; - data = data || {}; - dataType = dataType || undefined; - contentType = contentType || "application/json"; - - let response = null, - success = false; - - $.ajax({ - url: url, - async: false, - type: type, - data: data, - dataType: dataType, - contentType: contentType, - success: function(data) { - success = true; - response = data; - }, - error: function(data) { - success = false; - response = data; - }, - }); - - return { - success: success, - response: response - }; - } - -} - -export default App; diff --git a/webpack.config.js b/webpack.config.js index 99552a9b..ae4ec119 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -12,10 +12,10 @@ const ExtractTextPlugin = require("extract-text-webpack-plugin"); const banner = `/** * CyberChef - The Cyber Swiss Army Knife * - * @copyright Crown Copyright 2017 + * @copyright Crown Copyright 2016 * @license Apache-2.0 * - * Copyright 2017 Crown Copyright + * Copyright 2016 Crown Copyright * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.