From e92ed13864d5e404fa9986e6972b61ca83a7123a Mon Sep 17 00:00:00 2001 From: n1073645 Date: Thu, 21 Nov 2019 12:53:44 +0000 Subject: [PATCH 001/111] PLIST viewer. --- src/core/operations/PLISTViewer.mjs | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/core/operations/PLISTViewer.mjs diff --git a/src/core/operations/PLISTViewer.mjs b/src/core/operations/PLISTViewer.mjs new file mode 100644 index 00000000..1d263468 --- /dev/null +++ b/src/core/operations/PLISTViewer.mjs @@ -0,0 +1,56 @@ +/** + * @author n1073645 [n1073645@gmail.com] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; + +/** + * PLIST Viewer operation + */ +class PLISTViewer extends Operation { + + /** + * PLISTViewer constructor + */ + constructor() { + super(); + + this.name = "PLIST Viewer"; + this.module = "Other"; + this.description = "Converts PLISTXML file into a human readable format."; + this.infoURL = ""; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + /* Example arguments. See the project wiki for full details. + { + name: "First arg", + type: "string", + value: "Don't Panic" + }, + { + name: "Second arg", + type: "number", + value: 42 + } + */ + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + // const [firstArg, secondArg] = args; + + throw new OperationError("Test"); + } + +} + +export default PLISTViewer; From 63bb19d48d06c8e780ba402f2abb0274e0ecc250 Mon Sep 17 00:00:00 2001 From: n1073645 Date: Fri, 22 Nov 2019 08:32:46 +0000 Subject: [PATCH 002/111] Began implementing the PLIST viewer operation --- src/core/config/Categories.json | 1 + src/core/operations/PLISTViewer.mjs | 111 +++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 4 deletions(-) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index f663e16d..11e8f076 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -422,6 +422,7 @@ "Frequency distribution", "Index of Coincidence", "Chi Square", + "PLIST Viewer", "Disassemble x86", "Pseudo-Random Number Generator", "Generate UUID", diff --git a/src/core/operations/PLISTViewer.mjs b/src/core/operations/PLISTViewer.mjs index 1d263468..6229d336 100644 --- a/src/core/operations/PLISTViewer.mjs +++ b/src/core/operations/PLISTViewer.mjs @@ -5,7 +5,6 @@ */ import Operation from "../Operation.mjs"; -import OperationError from "../errors/OperationError.mjs"; /** * PLIST Viewer operation @@ -46,11 +45,115 @@ class PLISTViewer extends Operation { * @returns {string} */ run(input, args) { - // const [firstArg, secondArg] = args; - throw new OperationError("Test"); + const reserved = [["","",8], + ["","",6], + ["","",9], + ["","", 6], + ["","",6], + ["","",7], + ["","",6], + ["","",5], + ["",false,8], + ["",true,7]]; + + function the_viewer(input, dictionary_flag){ + var new_dict = new Array(); + var result = new Array(); + var new_key = null; + while(dictionary_flag ? input.slice(0,7) != "" : input.slice(0,8) != ""){ + reserved.forEach( function (elem, index){ + var element = elem[0]; + var endelement = elem[1]; + var length = elem[2]; + let temp = input.slice(0,length); + if(temp == element){ + input = input.slice(length); + if(temp == ""){ + var returned = the_viewer(input, true); + input = returned[1]; + if(new_key) + new_dict[new_key] = returned[0]; + else + new_dict["plist"] = returned[0]; + new_key = null; + }else if(temp == ""){ + var returned = the_viewer(input, false); + if(dictionary_flag) + new_dict[new_key] = returned[0]; + else + result.push(returned[0]); + input = returned[1]; + new_key = null; + }else if(temp == ""){ + var end = input.indexOf(endelement); + new_key = input.slice(0, end); + input = input.slice(end+length+1); + }else if(temp == "" || temp == ""){ + new_dict[new_key] = endelement; + new_key = null; + }else{ + var end = input.indexOf(endelement); + var toadd = input.slice(0, end); + if(temp == "") + toadd = parseInt(toadd); + else if(temp == "") + toadd = parseFloat(toadd); + if(dictionary_flag){ + new_dict[new_key] = toadd; + new_key = null; + }else{ + result.push(toadd); + } + input = input.slice(end+length+1); + } + } + }); + } + if(dictionary_flag){ + input = input.slice(7); + return [new_dict, input]; + }else{ + input = input.slice(8); + return [result, input]; + } + } + + let result = ""; + function print_it(input, depth) { + Object.keys(input).forEach((key, index) => { + if(typeof(input[key]) == "object") { + result += (("\t".repeat(depth)) + key + ": {\n"); + print_it(input[key], depth+1); + result += (("\t".repeat(depth)) + "}\n"); + } else { + result += (("\t".repeat(depth)) + key + " : " + input[key] + "\n"); + } + }); + } + + while (input.indexOf("/, ""); + } + while (input.indexOf("") !== -1){ + input = input.replace(/<\/plist>/, ""); + } + console.log(input); + while(input.indexOf("\n") !== -1) + input = input.replace("\n", ""); + while(input.indexOf("\t") !== -1) + input = input.replace("\t", ""); + while(input.indexOf(" ") !== -1) + input = input.replace(" ", ""); + console.log(input); + input = input.slice(input.indexOf("")+6); + //return input + var other = the_viewer(input, 1); + print_it(other[0],1); + result = "{\n" + result; + result += "}"; + return result; } - } export default PLISTViewer; From 8e1e1d56cadbb1465a323adec3ac544e9c53f3af Mon Sep 17 00:00:00 2001 From: n1073645 Date: Fri, 22 Nov 2019 15:39:43 +0000 Subject: [PATCH 003/111] Plist viewer operation added. --- src/core/operations/PLISTViewer.mjs | 156 ++++++++++------------------ 1 file changed, 55 insertions(+), 101 deletions(-) diff --git a/src/core/operations/PLISTViewer.mjs b/src/core/operations/PLISTViewer.mjs index 6229d336..939b7d1a 100644 --- a/src/core/operations/PLISTViewer.mjs +++ b/src/core/operations/PLISTViewer.mjs @@ -46,112 +46,66 @@ class PLISTViewer extends Operation { */ run(input, args) { - const reserved = [["","",8], - ["","",6], - ["","",9], - ["","", 6], - ["","",6], - ["","",7], - ["","",6], - ["","",5], - ["",false,8], - ["",true,7]]; - - function the_viewer(input, dictionary_flag){ - var new_dict = new Array(); - var result = new Array(); - var new_key = null; - while(dictionary_flag ? input.slice(0,7) != "" : input.slice(0,8) != ""){ - reserved.forEach( function (elem, index){ - var element = elem[0]; - var endelement = elem[1]; - var length = elem[2]; - let temp = input.slice(0,length); - if(temp == element){ - input = input.slice(length); - if(temp == ""){ - var returned = the_viewer(input, true); - input = returned[1]; - if(new_key) - new_dict[new_key] = returned[0]; - else - new_dict["plist"] = returned[0]; - new_key = null; - }else if(temp == ""){ - var returned = the_viewer(input, false); - if(dictionary_flag) - new_dict[new_key] = returned[0]; - else - result.push(returned[0]); - input = returned[1]; - new_key = null; - }else if(temp == ""){ - var end = input.indexOf(endelement); - new_key = input.slice(0, end); - input = input.slice(end+length+1); - }else if(temp == "" || temp == ""){ - new_dict[new_key] = endelement; - new_key = null; - }else{ - var end = input.indexOf(endelement); - var toadd = input.slice(0, end); - if(temp == "") - toadd = parseInt(toadd); - else if(temp == "") - toadd = parseFloat(toadd); - if(dictionary_flag){ - new_dict[new_key] = toadd; - new_key = null; - }else{ - result.push(toadd); - } - input = input.slice(end+length+1); - } - } - }); - } - if(dictionary_flag){ - input = input.slice(7); - return [new_dict, input]; - }else{ - input = input.slice(8); - return [result, input]; - } - } - + // Regexes are designed to transform the xml format into a reasonably more readable string format. + input = input.slice(input.indexOf("/g, "plist => ") + .replace(//g, "{") + .replace(/<\/dict>/g, "}") + .replace(//g, "[") + .replace(/<\/array>/g, "]") + .replace(/.+<\/key>/g, m => `${m.slice(5, m.indexOf(/<\/key>/g)-5)}\t=> `) + .replace(/.+<\/real>/g, m => `${m.slice(6, m.indexOf(/<\/real>/g)-6)}\n`) + .replace(/.+<\/string>/g, m => `${m.slice(8, m.indexOf(/<\/string>/g)-8)}\n`) + .replace(/.+<\/integer>/g, m => `${m.slice(9, m.indexOf(/<\/integer>/g)-9)}\n`) + .replace(//g, m => "false") + .replace(//g, m => "true") + .replace(/<\/plist>/g, "/plist") + .replace(/.+<\/date>/g, m => `${m.slice(6, m.indexOf(/<\/integer>/g)-6)}`) + .replace(/(\s|.)+?<\/data>/g, m => `${m.slice(6, m.indexOf(/<\/data>/g)-6)}`) + .replace(/[ \t\r\f\v]/g, ""); + let result = ""; - function print_it(input, depth) { - Object.keys(input).forEach((key, index) => { - if(typeof(input[key]) == "object") { - result += (("\t".repeat(depth)) + key + ": {\n"); - print_it(input[key], depth+1); - result += (("\t".repeat(depth)) + "}\n"); + + /** + * Formats the input after the regex has replaced all of the relevant parts. + * + * @param {array} input + * @param {number} depthCount + */ + function printIt(input, depthCount) { + if (!(input.length)) + return; + + // If the current position points at a larger dynamic structure. + if (input[0].indexOf("=>") !== -1) { + + // If the LHS also points at a larger structure (nested plists in a dictionary). + if (input[1].indexOf("=>") !== -1) { + result += ("\t".repeat(depthCount)) + input[0].slice(0, -2) + " => " + input[1].slice(0, -2) + " =>\n"; } else { - result += (("\t".repeat(depth)) + key + " : " + input[key] + "\n"); + result += ("\t".repeat(depthCount)) + input[0].slice(0, -2) + " => " + input[1] + "\n"; } - }); + + // Controls the tab depth for how many opening braces there have been. + if (input[1] === "{" || input[1] === "[") { + depthCount += 1; + } + input = input.slice(1); + } else { + // Controls the tab depth for how many closing braces there have been. + if (input[0] === "}" || input[0] === "]") + depthCount--; + + // Has to be here since the formatting breaks otherwise. + result += ("\t".repeat(depthCount)) + input[0] + "\n"; + if (input[0] === "{" || input[0] === "[") + depthCount++; + } + printIt(input.slice(1), depthCount); } - while (input.indexOf("/, ""); - } - while (input.indexOf("") !== -1){ - input = input.replace(/<\/plist>/, ""); - } - console.log(input); - while(input.indexOf("\n") !== -1) - input = input.replace("\n", ""); - while(input.indexOf("\t") !== -1) - input = input.replace("\t", ""); - while(input.indexOf(" ") !== -1) - input = input.replace(" ", ""); - console.log(input); - input = input.slice(input.indexOf("")+6); - //return input - var other = the_viewer(input, 1); - print_it(other[0],1); - result = "{\n" + result; - result += "}"; + input = input.split("\n").filter(e => e !== ""); + printIt(input, 0); return result; } } From 0295d0c9b47d6cd6b30492ce3b77b3741414cde9 Mon Sep 17 00:00:00 2001 From: n1073645 Date: Mon, 25 Nov 2019 10:35:45 +0000 Subject: [PATCH 004/111] Tided up presentation of the PLIST --- src/core/operations/PLISTViewer.mjs | 71 +++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/src/core/operations/PLISTViewer.mjs b/src/core/operations/PLISTViewer.mjs index 939b7d1a..8232fb14 100644 --- a/src/core/operations/PLISTViewer.mjs +++ b/src/core/operations/PLISTViewer.mjs @@ -55,7 +55,7 @@ class PLISTViewer extends Operation { .replace(/<\/array>/g, "]") .replace(/.+<\/key>/g, m => `${m.slice(5, m.indexOf(/<\/key>/g)-5)}\t=> `) .replace(/.+<\/real>/g, m => `${m.slice(6, m.indexOf(/<\/real>/g)-6)}\n`) - .replace(/.+<\/string>/g, m => `${m.slice(8, m.indexOf(/<\/string>/g)-8)}\n`) + .replace(/.+<\/string>/g, m => `"${m.slice(8, m.indexOf(/<\/string>/g)-8)}"\n`) .replace(/.+<\/integer>/g, m => `${m.slice(9, m.indexOf(/<\/integer>/g)-9)}\n`) .replace(//g, m => "false") .replace(//g, m => "true") @@ -64,44 +64,77 @@ class PLISTViewer extends Operation { .replace(/(\s|.)+?<\/data>/g, m => `${m.slice(6, m.indexOf(/<\/data>/g)-6)}`) .replace(/[ \t\r\f\v]/g, ""); + /** + * Depending on the type of brace, it will increment the depth and amount of arrays accordingly. + * + * @param {string} elem + * @param {array} vals + * @param {number} offset + */ + function braces(elem, vals,offset) { + let temp = vals.indexOf(elem); + if (temp !== -1) { + depthCount += offset; + if (temp === 1) + arrCount += offset; + } + } + let result = ""; + let arrCount = 0; + let depthCount = 0; /** * Formats the input after the regex has replaced all of the relevant parts. * * @param {array} input - * @param {number} depthCount + * @param {number} index */ - function printIt(input, depthCount) { + function printIt(input, index) { if (!(input.length)) return; + let temp = ""; + const origArr = arrCount; + let currElem = input[0]; + // If the current position points at a larger dynamic structure. - if (input[0].indexOf("=>") !== -1) { + if (currElem.indexOf("=>") !== -1) { // If the LHS also points at a larger structure (nested plists in a dictionary). - if (input[1].indexOf("=>") !== -1) { - result += ("\t".repeat(depthCount)) + input[0].slice(0, -2) + " => " + input[1].slice(0, -2) + " =>\n"; - } else { - result += ("\t".repeat(depthCount)) + input[0].slice(0, -2) + " => " + input[1] + "\n"; - } + if (input[1].indexOf("=>") !== -1) + temp = currElem.slice(0, -2) + " => " + input[1].slice(0, -2) + " =>\n"; + else + temp = currElem.slice(0, -2) + " => " + input[1] + "\n"; - // Controls the tab depth for how many opening braces there have been. - if (input[1] === "{" || input[1] === "[") { - depthCount += 1; - } input = input.slice(1); } else { // Controls the tab depth for how many closing braces there have been. - if (input[0] === "}" || input[0] === "]") - depthCount--; + + braces(currElem, ["}", "]"], -1); // Has to be here since the formatting breaks otherwise. - result += ("\t".repeat(depthCount)) + input[0] + "\n"; - if (input[0] === "{" || input[0] === "[") - depthCount++; + temp = currElem + "\n"; } - printIt(input.slice(1), depthCount); + + currElem = input[0]; + + // Tab out to the correct distance. + result += ("\t".repeat(depthCount)); + + // If it is enclosed in an array show index. + if (arrCount > 0 && currElem !== "]") + result += index.toString() + " => "; + + result += temp; + + // Controls the tab depth for how many opening braces there have been. + braces(currElem, ["{", "["],1); + + // If there has been a new array then reset index. + if (arrCount > origArr) + return printIt(input.slice(1), 0); + return printIt(input.slice(1), ++index); } input = input.split("\n").filter(e => e !== ""); From d8405e5f814e17319dd293fdcddfdeeca2a43f15 Mon Sep 17 00:00:00 2001 From: n1073645 Date: Mon, 25 Nov 2019 10:37:30 +0000 Subject: [PATCH 005/111] Linting on PLIST viewer operation. --- src/core/operations/PLISTViewer.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/operations/PLISTViewer.mjs b/src/core/operations/PLISTViewer.mjs index 8232fb14..b8a90c5b 100644 --- a/src/core/operations/PLISTViewer.mjs +++ b/src/core/operations/PLISTViewer.mjs @@ -71,8 +71,8 @@ class PLISTViewer extends Operation { * @param {array} vals * @param {number} offset */ - function braces(elem, vals,offset) { - let temp = vals.indexOf(elem); + function braces(elem, vals, offset) { + const temp = vals.indexOf(elem); if (temp !== -1) { depthCount += offset; if (temp === 1) @@ -129,7 +129,7 @@ class PLISTViewer extends Operation { result += temp; // Controls the tab depth for how many opening braces there have been. - braces(currElem, ["{", "["],1); + braces(currElem, ["{", "["], 1); // If there has been a new array then reset index. if (arrCount > origArr) From 0259ed8314c0635124d7be316f9e9ec583f4cce0 Mon Sep 17 00:00:00 2001 From: n1073645 Date: Mon, 27 Jan 2020 16:07:54 +0000 Subject: [PATCH 006/111] LS47 implemented, needs linting --- src/core/lib/LS47.mjs | 148 ++++++++++++++++++++++++++++ src/core/operations/LS47Decrypt.mjs | 58 +++++++++++ src/core/operations/LS47Encrypt.mjs | 63 ++++++++++++ 3 files changed, 269 insertions(+) create mode 100644 src/core/lib/LS47.mjs create mode 100644 src/core/operations/LS47Decrypt.mjs create mode 100644 src/core/operations/LS47Encrypt.mjs diff --git a/src/core/lib/LS47.mjs b/src/core/lib/LS47.mjs new file mode 100644 index 00000000..a4ef10a5 --- /dev/null +++ b/src/core/lib/LS47.mjs @@ -0,0 +1,148 @@ +/** + * @author n1073645 [n1073645@gmail.com] + * @copyright Crown Copyright 2020 + * @license Apache-2.0 + */ + +import OperationError from "../errors/OperationError.mjs"; + +let letters = "_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()"; +let tiles = []; + +export function init_tiles() { + for (let i = 0; i < 49; i++) + tiles.push([letters.charAt(i), [Math.floor(i/7), i % 7]]); +} + +function rotate_down(key, col, n) { + let lines = []; + for (let i = 0; i < 7; i++) + lines.push(key.slice(i*7, (i + 1) * 7)); + let lefts = []; + let mids = []; + let rights = []; + lines.forEach((element) => { + lefts.push(element.slice(0, col)); + mids.push(element.charAt(col)); + rights.push(element.slice(col+1)); + }); + n = (7 - n % 7) % 7; + mids = mids.slice(n).concat(mids.slice(0, n)); + let result = ""; + for (let i = 0; i < 7; i++) + result += lefts[i] + mids[i] + rights[i]; + return result; +} + +function rotate_right(key, row, n) { + let mid = key.slice(row * 7, (row + 1) * 7); + n = (7 - n % 7) % 7; + return key.slice(0, 7 * row) + mid.slice(n) + mid.slice(0, n) + key.slice(7 * (row + 1)); +} + +function find_ix(letter) { + for (let i = 0; i < tiles.length; i++) + if (tiles[i][0] === letter) + return tiles[i][1]; + throw new OperationError("Letter " + letter + " is not included in LS47"); +} + +export function derive_key(password) { + let i = 0; + let k = letters; + for (const c of password) { + let [row, col] = find_ix(c); + k = rotate_down(rotate_right(k, i, col), i, row); + i = (i + 1) % 7; + } + return k; +} + +function check_key(key) { + if (key.length !== letters.length) + throw new OperationError("Wrong key size"); + let counts = new Array(); + for (let i = 0; i < letters.length; i++) + counts[letters.charAt(i)] = 0; + for (const elem of letters){ + if (letters.indexOf(elem) === -1) + throw new OperationError("Letter " + elem + " not in LS47!"); + counts[elem]++; + if (counts[elem] > 1) + throw new OperationError("Letter duplicated in the key!"); + } +} + +function find_pos (key, letter) { + let index = key.indexOf(letter); + if (index >= 0 && index < 49) + return [Math.floor(index/7), index%7]; + throw new OperationError("Letter " + letter + " is not in the key!"); +} + +function find_at_pos(key, coord) { + return key.charAt(coord[1] + (coord[0] * 7)); +} + +function add_pos(a, b) { + return [(a[0] + b[0]) % 7, (a[1] + b[1]) % 7]; +} + +function sub_pos(a, b) { + let asub = a[0] - b[0]; + let bsub = a[1] - b[1]; + return [asub - (Math.floor(asub/7) * 7), bsub - (Math.floor(bsub/7) * 7)]; +} + +function encrypt(key, plaintext) { + check_key(key); + let mp = [0, 0]; + let ciphertext = ''; + for (const p of plaintext) { + let pp = find_pos(key, p); + let mix = find_ix(find_at_pos(key, mp)); + let cp = add_pos(pp, mix); + let c = find_at_pos(key, cp); + ciphertext += c; + key = rotate_right(key, pp[0], 1); + cp = find_pos(key, c); + key = rotate_down(key, cp[1], 1); + mp = add_pos(mp, find_ix(c)); + } + return ciphertext; +} + +function decrypt(key, ciphertext) { + check_key(key); + let mp = [0,0]; + let plaintext = ''; + for (const c of ciphertext) { + let cp = find_pos(key, c); + let mix = find_ix(find_at_pos(key, mp)); + let pp = sub_pos(cp, mix); + let p = find_at_pos(key, pp); + + plaintext += p; + key = rotate_right(key, pp[0], 1); + cp = find_pos(key, c); + key = rotate_down(key, cp[1], 1); + mp = add_pos(mp, find_ix(c)); + } + return plaintext; +} + +export function encrypt_pad(key, plaintext, signature, padding_size) { + init_tiles(); + check_key(key); + let padding = ""; + for (let i = 0; i < padding_size; i++) { + padding += letters.charAt(Math.floor(Math.random() * letters.length)); + } + return encrypt(key, padding+plaintext+'---'+signature); +} + +export function decrypt_pad(key, ciphertext, padding_size) { + init_tiles(); + check_key(key); + return decrypt(key, ciphertext).slice(padding_size); +} \ No newline at end of file diff --git a/src/core/operations/LS47Decrypt.mjs b/src/core/operations/LS47Decrypt.mjs new file mode 100644 index 00000000..ffda8f93 --- /dev/null +++ b/src/core/operations/LS47Decrypt.mjs @@ -0,0 +1,58 @@ +/** + * @author n1073645 [n1073645@gmail.com] + * @copyright Crown Copyright 2020 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import * as LS47 from "../lib/LS47.mjs" + +/** + * LS47 Decrypt operation + */ +class LS47Decrypt extends Operation { + + /** + * LS47Decrypt constructor + */ + constructor() { + super(); + + this.name = "LS47 Decrypt"; + this.module = "Crypto"; + this.description = ""; + this.infoURL = ""; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Password", + type: "string", + value: "" + }, + { + name: "Padding", + type: "number", + value: 10 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + + this.padding_size = parseInt(args[1], 10); + + LS47.init_tiles(); + + let key = LS47.derive_key(args[0]); + return LS47.decrypt_pad(key, input, this.padding_size); + } + +} + +export default LS47Decrypt; diff --git a/src/core/operations/LS47Encrypt.mjs b/src/core/operations/LS47Encrypt.mjs new file mode 100644 index 00000000..bf3b0306 --- /dev/null +++ b/src/core/operations/LS47Encrypt.mjs @@ -0,0 +1,63 @@ +/** + * @author n1073645 [n1073645@gmail.com] + * @copyright Crown Copyright 2020 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import * as LS47 from "../lib/LS47.mjs" + +/** + * LS47 Encrypt operation + */ +class LS47Encrypt extends Operation { + + /** + * LS47Encrypt constructor + */ + constructor() { + super(); + + this.name = "LS47 Encrypt"; + this.module = "Crypto"; + this.description = ""; + this.infoURL = ""; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Password", + type: "string", + value: "" + }, + { + name: "Padding", + type: "number", + value: 10 + }, + { + name: "Signature", + type: "string", + value: "" + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + + this.padding_size = parseInt(args[1], 10); + + LS47.init_tiles(); + + let key = LS47.derive_key(args[0]); + return LS47.encrypt_pad(key, input, args[2], this.padding_size); + } + +} + +export default LS47Encrypt; From 5cdd062ed9c639bf387c783667d8bd86302e8acb Mon Sep 17 00:00:00 2001 From: n1073645 Date: Tue, 28 Jan 2020 09:33:32 +0000 Subject: [PATCH 007/111] Linting done --- src/core/config/Categories.json | 2 + src/core/lib/LS47.mjs | 153 ++++++++++++++++++---------- src/core/operations/LS47Decrypt.mjs | 12 +-- src/core/operations/LS47Encrypt.mjs | 14 +-- 4 files changed, 112 insertions(+), 69 deletions(-) diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 53ca796d..1b810d37 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -75,6 +75,8 @@ "DES Decrypt", "Triple DES Encrypt", "Triple DES Decrypt", + "LS47 Encrypt", + "LS47 Decrypt", "RC2 Encrypt", "RC2 Decrypt", "RC4", diff --git a/src/core/lib/LS47.mjs b/src/core/lib/LS47.mjs index a4ef10a5..b028fc4f 100644 --- a/src/core/lib/LS47.mjs +++ b/src/core/lib/LS47.mjs @@ -6,21 +6,27 @@ import OperationError from "../errors/OperationError.mjs"; -let letters = "_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()"; -let tiles = []; +const letters = "_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()"; +const tiles = []; -export function init_tiles() { +/** + * + */ +export function initTiles() { for (let i = 0; i < 49; i++) tiles.push([letters.charAt(i), [Math.floor(i/7), i % 7]]); } -function rotate_down(key, col, n) { - let lines = []; - for (let i = 0; i < 7; i++) +/** + * + */ +function rotateDown(key, col, n) { + const lines = []; + for (let i = 0; i < 7; i++) lines.push(key.slice(i*7, (i + 1) * 7)); - let lefts = []; + const lefts = []; let mids = []; - let rights = []; + const rights = []; lines.forEach((element) => { lefts.push(element.slice(0, col)); mids.push(element.charAt(col)); @@ -34,37 +40,49 @@ function rotate_down(key, col, n) { return result; } -function rotate_right(key, row, n) { - let mid = key.slice(row * 7, (row + 1) * 7); +/** + * + */ +function rotateRight(key, row, n) { + const mid = key.slice(row * 7, (row + 1) * 7); n = (7 - n % 7) % 7; return key.slice(0, 7 * row) + mid.slice(n) + mid.slice(0, n) + key.slice(7 * (row + 1)); } -function find_ix(letter) { +/** + * + */ +function findIx(letter) { for (let i = 0; i < tiles.length; i++) if (tiles[i][0] === letter) return tiles[i][1]; throw new OperationError("Letter " + letter + " is not included in LS47"); } -export function derive_key(password) { +/** + * + */ +export function deriveKey(password) { let i = 0; let k = letters; for (const c of password) { - let [row, col] = find_ix(c); - k = rotate_down(rotate_right(k, i, col), i, row); + const [row, col] = findIx(c); + k = rotateDown(rotateRight(k, i, col), i, row); i = (i + 1) % 7; } return k; } -function check_key(key) { +/** + * + */ +function checkKey(key) { if (key.length !== letters.length) throw new OperationError("Wrong key size"); - let counts = new Array(); + const counts = new Array(); for (let i = 0; i < letters.length; i++) counts[letters.charAt(i)] = 0; - for (const elem of letters){ + for (const elem of letters) { if (letters.indexOf(elem) === -1) throw new OperationError("Letter " + elem + " not in LS47!"); counts[elem]++; @@ -73,76 +91,99 @@ function check_key(key) { } } -function find_pos (key, letter) { - let index = key.indexOf(letter); +/** + * + */ +function findPos (key, letter) { + const index = key.indexOf(letter); if (index >= 0 && index < 49) return [Math.floor(index/7), index%7]; throw new OperationError("Letter " + letter + " is not in the key!"); } -function find_at_pos(key, coord) { +/** + * + */ +function findAtPos(key, coord) { return key.charAt(coord[1] + (coord[0] * 7)); } -function add_pos(a, b) { +/** + * + */ +function addPos(a, b) { return [(a[0] + b[0]) % 7, (a[1] + b[1]) % 7]; } -function sub_pos(a, b) { - let asub = a[0] - b[0]; - let bsub = a[1] - b[1]; +/** + * + */ +function subPos(a, b) { + const asub = a[0] - b[0]; + const bsub = a[1] - b[1]; return [asub - (Math.floor(asub/7) * 7), bsub - (Math.floor(bsub/7) * 7)]; } +/** + * + */ function encrypt(key, plaintext) { - check_key(key); + checkKey(key); let mp = [0, 0]; - let ciphertext = ''; + let ciphertext = ""; for (const p of plaintext) { - let pp = find_pos(key, p); - let mix = find_ix(find_at_pos(key, mp)); - let cp = add_pos(pp, mix); - let c = find_at_pos(key, cp); + const pp = findPos(key, p); + const mix = findIx(findAtPos(key, mp)); + let cp = addPos(pp, mix); + const c = findAtPos(key, cp); ciphertext += c; - key = rotate_right(key, pp[0], 1); - cp = find_pos(key, c); - key = rotate_down(key, cp[1], 1); - mp = add_pos(mp, find_ix(c)); + key = rotateRight(key, pp[0], 1); + cp = findPos(key, c); + key = rotateDown(key, cp[1], 1); + mp = addPos(mp, findIx(c)); } return ciphertext; } +/** + * + */ function decrypt(key, ciphertext) { - check_key(key); - let mp = [0,0]; - let plaintext = ''; + checkKey(key); + let mp = [0, 0]; + let plaintext = ""; for (const c of ciphertext) { - let cp = find_pos(key, c); - let mix = find_ix(find_at_pos(key, mp)); - let pp = sub_pos(cp, mix); - let p = find_at_pos(key, pp); - + let cp = findPos(key, c); + const mix = findIx(findAtPos(key, mp)); + const pp = subPos(cp, mix); + const p = findAtPos(key, pp); plaintext += p; - key = rotate_right(key, pp[0], 1); - cp = find_pos(key, c); - key = rotate_down(key, cp[1], 1); - mp = add_pos(mp, find_ix(c)); + key = rotateRight(key, pp[0], 1); + cp = findPos(key, c); + key = rotateDown(key, cp[1], 1); + mp = addPos(mp, findIx(c)); } return plaintext; } -export function encrypt_pad(key, plaintext, signature, padding_size) { - init_tiles(); - check_key(key); +/** + * + */ +export function encryptPad(key, plaintext, signature, paddingSize) { + initTiles(); + checkKey(key); let padding = ""; - for (let i = 0; i < padding_size; i++) { + for (let i = 0; i < paddingSize; i++) { padding += letters.charAt(Math.floor(Math.random() * letters.length)); } - return encrypt(key, padding+plaintext+'---'+signature); + return encrypt(key, padding+plaintext+"---"+signature); } -export function decrypt_pad(key, ciphertext, padding_size) { - init_tiles(); - check_key(key); - return decrypt(key, ciphertext).slice(padding_size); -} \ No newline at end of file +/** + * + */ +export function decryptPad(key, ciphertext, paddingSize) { + initTiles(); + checkKey(key); + return decrypt(key, ciphertext).slice(paddingSize); +} diff --git a/src/core/operations/LS47Decrypt.mjs b/src/core/operations/LS47Decrypt.mjs index ffda8f93..a5a92ebf 100644 --- a/src/core/operations/LS47Decrypt.mjs +++ b/src/core/operations/LS47Decrypt.mjs @@ -5,7 +5,7 @@ */ import Operation from "../Operation.mjs"; -import * as LS47 from "../lib/LS47.mjs" +import * as LS47 from "../lib/LS47.mjs"; /** * LS47 Decrypt operation @@ -45,12 +45,12 @@ class LS47Decrypt extends Operation { */ run(input, args) { - this.padding_size = parseInt(args[1], 10); + this.paddingSize = parseInt(args[1], 10); - LS47.init_tiles(); - - let key = LS47.derive_key(args[0]); - return LS47.decrypt_pad(key, input, this.padding_size); + LS47.initTiles(); + + const key = LS47.deriveKey(args[0]); + return LS47.decryptPad(key, input, this.paddingSize); } } diff --git a/src/core/operations/LS47Encrypt.mjs b/src/core/operations/LS47Encrypt.mjs index bf3b0306..f82baaab 100644 --- a/src/core/operations/LS47Encrypt.mjs +++ b/src/core/operations/LS47Encrypt.mjs @@ -5,7 +5,7 @@ */ import Operation from "../Operation.mjs"; -import * as LS47 from "../lib/LS47.mjs" +import * as LS47 from "../lib/LS47.mjs"; /** * LS47 Encrypt operation @@ -49,13 +49,13 @@ class LS47Encrypt extends Operation { * @returns {string} */ run(input, args) { - - this.padding_size = parseInt(args[1], 10); - LS47.init_tiles(); - - let key = LS47.derive_key(args[0]); - return LS47.encrypt_pad(key, input, args[2], this.padding_size); + this.paddingSize = parseInt(args[1], 10); + + LS47.initTiles(); + + const key = LS47.deriveKey(args[0]); + return LS47.encryptPad(key, input, args[2], this.paddingSize); } } From 6fd929160d9eb5ee332af80c90e823513b0a86f1 Mon Sep 17 00:00:00 2001 From: n1073645 Date: Tue, 28 Jan 2020 10:35:01 +0000 Subject: [PATCH 008/111] Comments and linting. --- src/core/lib/LS47.mjs | 57 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/core/lib/LS47.mjs b/src/core/lib/LS47.mjs index b028fc4f..6696aafc 100644 --- a/src/core/lib/LS47.mjs +++ b/src/core/lib/LS47.mjs @@ -10,7 +10,7 @@ const letters = "_abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()"; const tiles = []; /** - * + * Initialises the tiles with values and positions. */ export function initTiles() { for (let i = 0; i < 49; i++) @@ -18,7 +18,12 @@ export function initTiles() { } /** + * Rotates the key "down". * + * @param {string} key + * @param {number} col + * @param {number} n + * @returns {string} */ function rotateDown(key, col, n) { const lines = []; @@ -41,7 +46,12 @@ function rotateDown(key, col, n) { } /** + * Rotates the key "right". * + * @param {string} key + * @param {number} row + * @param {number} n + * @returns {string} */ function rotateRight(key, row, n) { const mid = key.slice(row * 7, (row + 1) * 7); @@ -50,7 +60,10 @@ function rotateRight(key, row, n) { } /** + * Finds the position of a letter in the tiles. * + * @param {string} letter + * @returns {string} */ function findIx(letter) { for (let i = 0; i < tiles.length; i++) @@ -60,7 +73,10 @@ function findIx(letter) { } /** + * Derives key from the input password. * + * @param {string} password + * @returns {string} */ export function deriveKey(password) { let i = 0; @@ -74,7 +90,9 @@ export function deriveKey(password) { } /** + * Checks the key is a valid key. * + * @param {string} key */ function checkKey(key) { if (key.length !== letters.length) @@ -92,7 +110,11 @@ function checkKey(key) { } /** + * Finds the position of a letter in they key. * + * @param {letter} key + * @param {string} letter + * @returns {object} */ function findPos (key, letter) { const index = key.indexOf(letter); @@ -102,21 +124,35 @@ function findPos (key, letter) { } /** + * Returns the character at the position on the tiles. * + * @param {string} key + * @param {object} coord + * @returns {string} */ function findAtPos(key, coord) { return key.charAt(coord[1] + (coord[0] * 7)); } /** + * Returns new position by adding two positions. * + * @param {object} a + * @param {object} b + * @returns {object} */ function addPos(a, b) { return [(a[0] + b[0]) % 7, (a[1] + b[1]) % 7]; } /** + * Returns new position by subtracting two positions. + * Note: We have to manually do the remainder division, since JS does not + * operate correctly on negative numbers (e.g. -3 % 4 = -3 when it should be 1). * + * @param {object} a + * @param {object} b + * @returns {object} */ function subPos(a, b) { const asub = a[0] - b[0]; @@ -125,7 +161,11 @@ function subPos(a, b) { } /** + * Encrypts the plaintext string. * + * @param {string} key + * @param {string} plaintext + * @returns {string} */ function encrypt(key, plaintext) { checkKey(key); @@ -146,7 +186,11 @@ function encrypt(key, plaintext) { } /** + * Decrypts the ciphertext string. * + * @param {string} key + * @param {string} ciphertext + * @returns {string} */ function decrypt(key, ciphertext) { checkKey(key); @@ -167,7 +211,13 @@ function decrypt(key, ciphertext) { } /** + * Adds padding to the input. * + * @param {string} key + * @param {string} plaintext + * @param {string} signature + * @param {number} paddingSize + * @returns {string} */ export function encryptPad(key, plaintext, signature, paddingSize) { initTiles(); @@ -180,7 +230,12 @@ export function encryptPad(key, plaintext, signature, paddingSize) { } /** + * Removes padding from the ouput. * + * @param {string} key + * @param {string} ciphertext + * @param {number} paddingSize + * @returns {string} */ export function decryptPad(key, ciphertext, paddingSize) { initTiles(); From e71794d362cf8112fc940a2ae6177c84ffce3bb5 Mon Sep 17 00:00:00 2001 From: n1073645 Date: Fri, 14 Feb 2020 12:28:12 +0000 Subject: [PATCH 009/111] Tests added for LS47 --- src/core/operations/LS47Decrypt.mjs | 4 +-- src/core/operations/LS47Encrypt.mjs | 4 +-- tests/operations/index.mjs | 1 + tests/operations/tests/LS47.mjs | 45 +++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 tests/operations/tests/LS47.mjs diff --git a/src/core/operations/LS47Decrypt.mjs b/src/core/operations/LS47Decrypt.mjs index a5a92ebf..cb92cd27 100644 --- a/src/core/operations/LS47Decrypt.mjs +++ b/src/core/operations/LS47Decrypt.mjs @@ -20,8 +20,8 @@ class LS47Decrypt extends Operation { this.name = "LS47 Decrypt"; this.module = "Crypto"; - this.description = ""; - this.infoURL = ""; + this.description = "This is a slight improvement of the ElsieFour cipher as described by Alan Kaminsky. We use 7x7 characters instead of original (barely fitting) 6x6, to be able to encrypt some structured information. We also describe a simple key-expansion algorithm, because remembering passwords is popular. Similar security considerations as with ElsieFour hold.\nThe LS47 alphabet consists of following characters: _abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()\nA LS47 key is a permutation of the alphabet that is then represented in a 7x7 grid used for the encryption or decryption."; + this.infoURL = "https://gitea.blesmrt.net/exa/ls47/src/branch/master"; this.inputType = "string"; this.outputType = "string"; this.args = [ diff --git a/src/core/operations/LS47Encrypt.mjs b/src/core/operations/LS47Encrypt.mjs index f82baaab..51283844 100644 --- a/src/core/operations/LS47Encrypt.mjs +++ b/src/core/operations/LS47Encrypt.mjs @@ -20,8 +20,8 @@ class LS47Encrypt extends Operation { this.name = "LS47 Encrypt"; this.module = "Crypto"; - this.description = ""; - this.infoURL = ""; + this.description = "This is a slight improvement of the ElsieFour cipher as described by Alan Kaminsky. We use 7x7 characters instead of original (barely fitting) 6x6, to be able to encrypt some structured information. We also describe a simple key-expansion algorithm, because remembering passwords is popular. Similar security considerations as with ElsieFour hold.\nThe LS47 alphabet consists of following characters: _abcdefghijklmnopqrstuvwxyz.0123456789,-+*/:?!'()\nA LS47 key is a permutation of the alphabet that is then represented in a 7x7 grid used for the encryption or decryption."; + this.infoURL = "https://gitea.blesmrt.net/exa/ls47/src/branch/master"; this.inputType = "string"; this.outputType = "string"; this.args = [ diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index bf440414..b3731727 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -96,6 +96,7 @@ import "./tests/DefangIP.mjs"; import "./tests/ParseUDP.mjs"; import "./tests/AvroToJSON.mjs"; import "./tests/Lorenz.mjs"; +import "./tests/LS47.mjs"; // Cannot test operations that use the File type yet diff --git a/tests/operations/tests/LS47.mjs b/tests/operations/tests/LS47.mjs new file mode 100644 index 00000000..40d876ee --- /dev/null +++ b/tests/operations/tests/LS47.mjs @@ -0,0 +1,45 @@ +/** + * Cartesian Product tests. + * + * @author n1073645 [n1073645@gmail.com] + * + * @copyright Crown Copyright 2020 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "LS47 Encrypt", + input: "thequickbrownfoxjumped", + expectedOutput: "(,t74ci78cp/8trx*yesu:alp1wqy", + recipeConfig: [ + { + op: "LS47 Encrypt", + args: ["helloworld", 0, "test"], + }, + ], + }, + { + name: "LS47 Decrypt", + input: "(,t74ci78cp/8trx*yesu:alp1wqy", + expectedOutput: "thequickbrownfoxjumped---test", + recipeConfig: [ + { + op: "LS47 Decrypt", + args: ["helloworld", 0], + }, + ], + }, + { + name: "LS47 Encrypt", + input: "thequickbrownfoxjumped", + expectedOutput: "Letter H is not included in LS47", + recipeConfig: [ + { + op: "LS47 Encrypt", + args: ["Helloworld", 0, "test"], + }, + ], + } +]); From e91e993fb5e7ec99db8fcb179fbd18a3f53b97bc Mon Sep 17 00:00:00 2001 From: n1073645 <57447333+n1073645@users.noreply.github.com> Date: Fri, 14 Feb 2020 13:43:30 +0000 Subject: [PATCH 010/111] Update LS47.mjs --- tests/operations/tests/LS47.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/operations/tests/LS47.mjs b/tests/operations/tests/LS47.mjs index 40d876ee..ce613923 100644 --- a/tests/operations/tests/LS47.mjs +++ b/tests/operations/tests/LS47.mjs @@ -1,5 +1,5 @@ /** - * Cartesian Product tests. + * LS47 tests. * * @author n1073645 [n1073645@gmail.com] * From 0182cdda69f7c877746084a75600d87b2cb34e19 Mon Sep 17 00:00:00 2001 From: Benedikt Werner <1benediktwerner@gmail.com> Date: Sat, 16 May 2020 00:42:02 +0200 Subject: [PATCH 011/111] Base85: Fix alphabetName --- src/core/lib/Base85.mjs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/lib/Base85.mjs b/src/core/lib/Base85.mjs index 8da729e2..e5778132 100644 --- a/src/core/lib/Base85.mjs +++ b/src/core/lib/Base85.mjs @@ -1,3 +1,5 @@ +import Utils from "../Utils.mjs"; + /** * Base85 resources. * @@ -32,13 +34,12 @@ export const ALPHABET_OPTIONS = [ * @returns {string} */ export function alphabetName(alphabet) { - alphabet = alphabet.replace("'", "'"); - alphabet = alphabet.replace("\"", """); - alphabet = alphabet.replace("\\", "\"); + alphabet = escape(alphabet); let name; ALPHABET_OPTIONS.forEach(function(a) { - if (escape(alphabet) === escape(a.value)) name = a.name; + const expanded = Utils.expandAlphRange(a.value).join(""); + if (alphabet === escape(expanded)) name = a.name; }); return name; From 103ecff6a7465b7a46a8f452885ec99d0e45ea26 Mon Sep 17 00:00:00 2001 From: Benedikt Werner <1benediktwerner@gmail.com> Date: Sat, 16 May 2020 00:42:31 +0200 Subject: [PATCH 012/111] Base85: Ignore whitespace --- src/core/operations/FromBase85.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/operations/FromBase85.mjs b/src/core/operations/FromBase85.mjs index c874d5dc..c0d0328e 100644 --- a/src/core/operations/FromBase85.mjs +++ b/src/core/operations/FromBase85.mjs @@ -52,6 +52,8 @@ class FromBase85 extends Operation { if (input.length === 0) return []; + input = input.replace(/\s+/g, ""); + const matches = input.match(/<~(.+?)~>/); if (matches !== null) input = matches[1]; From 15dd9d4c93fa5bcfb1341ad8dccdb5671ae08d22 Mon Sep 17 00:00:00 2001 From: Benedikt Werner <1benediktwerner@gmail.com> Date: Sat, 16 May 2020 00:42:50 +0200 Subject: [PATCH 013/111] Add magic checks for base85 --- src/core/operations/FromBase85.mjs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/core/operations/FromBase85.mjs b/src/core/operations/FromBase85.mjs index c0d0328e..42f37a1c 100644 --- a/src/core/operations/FromBase85.mjs +++ b/src/core/operations/FromBase85.mjs @@ -33,6 +33,23 @@ class FromBase85 extends Operation { value: ALPHABET_OPTIONS }, ]; + this.checks = [ + { + pattern: "^\\s*(?:<~)?(?:(?:\\s*[!-u]){5}|\\s*z)+[!-u\\s]*(?:~>)?\\s*$", + flags: "i", + args: ["!-u"] + }, + { + pattern: "^(?:\\s*[0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#])+\\s*$", + flags: "i", + args: ["0-9a-zA-Z.\\-:+=^!/*?&<>()[]{}@%$#"] + }, + { + pattern: "^(?:\\s*[0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~])+\\s*$", + flags: "i", + args: ["0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~"] + }, + ]; } /** From eab1be0e2c58c3d69f8b2c477e4102f601b611c7 Mon Sep 17 00:00:00 2001 From: Benedikt Werner <1benediktwerner@gmail.com> Date: Wed, 20 May 2020 00:23:50 +0200 Subject: [PATCH 014/111] Magic base85: Remove 'i' flag --- src/core/operations/FromBase85.mjs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/core/operations/FromBase85.mjs b/src/core/operations/FromBase85.mjs index 42f37a1c..22033f99 100644 --- a/src/core/operations/FromBase85.mjs +++ b/src/core/operations/FromBase85.mjs @@ -36,17 +36,14 @@ class FromBase85 extends Operation { this.checks = [ { pattern: "^\\s*(?:<~)?(?:(?:\\s*[!-u]){5}|\\s*z)+[!-u\\s]*(?:~>)?\\s*$", - flags: "i", args: ["!-u"] }, { pattern: "^(?:\\s*[0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#])+\\s*$", - flags: "i", args: ["0-9a-zA-Z.\\-:+=^!/*?&<>()[]{}@%$#"] }, { pattern: "^(?:\\s*[0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~])+\\s*$", - flags: "i", args: ["0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~"] }, ]; From 1294d764e258bb6caa739b6111bb6d79a61d394f Mon Sep 17 00:00:00 2001 From: Benedikt Werner <1benediktwerner@gmail.com> Date: Fri, 22 May 2020 03:30:15 +0200 Subject: [PATCH 015/111] Base85: Only remove start and end markers with standard/ascii85 encoding --- src/core/operations/FromBase85.mjs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/operations/FromBase85.mjs b/src/core/operations/FromBase85.mjs index 22033f99..09ded171 100644 --- a/src/core/operations/FromBase85.mjs +++ b/src/core/operations/FromBase85.mjs @@ -68,8 +68,10 @@ class FromBase85 extends Operation { input = input.replace(/\s+/g, ""); - const matches = input.match(/<~(.+?)~>/); - if (matches !== null) input = matches[1]; + if (encoding === "Standard") { + const matches = input.match(/<~(.+?)~>/); + if (matches !== null) input = matches[1]; + } let i = 0; let block, blockBytes; From ee408f7add6d633b9c42a6677f5bfa75055e9ca6 Mon Sep 17 00:00:00 2001 From: Benedikt Werner <1benediktwerner@gmail.com> Date: Fri, 22 May 2020 03:30:57 +0200 Subject: [PATCH 016/111] Base85: Update magic regexes to require 20 non-whitespace base85 chars --- src/core/operations/FromBase85.mjs | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/core/operations/FromBase85.mjs b/src/core/operations/FromBase85.mjs index 09ded171..9d73baa1 100644 --- a/src/core/operations/FromBase85.mjs +++ b/src/core/operations/FromBase85.mjs @@ -35,16 +35,31 @@ class FromBase85 extends Operation { ]; this.checks = [ { - pattern: "^\\s*(?:<~)?(?:(?:\\s*[!-u]){5}|\\s*z)+[!-u\\s]*(?:~>)?\\s*$", - args: ["!-u"] + pattern: + "^\\s*(?:<~)?" + // Optional whitespace and starting marker + "[\\s!-uz]*" + // Any amount of base85 characters and whitespace + "[!-uz]{20}" + // At least 20 continoues base85 characters without whitespace + "[\\s!-uz]*" + // Any amount of base85 characters and whitespace + "(?:~>)?\\s*$", // Optional ending marker and whitespace + args: ["!-u"], }, { - pattern: "^(?:\\s*[0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#])+\\s*$", - args: ["0-9a-zA-Z.\\-:+=^!/*?&<>()[]{}@%$#"] + pattern: + "^" + + "[\\s0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]*" + + "[0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]{20}" + // At least 20 continoues base85 characters without whitespace + "[\\s0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]*" + + "$", + args: ["0-9a-zA-Z.\\-:+=^!/*?&<>()[]{}@%$#"], }, { - pattern: "^(?:\\s*[0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~])+\\s*$", - args: ["0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~"] + pattern: + "^" + + "[\\s0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]*" + + "[0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]{20}" + // At least 20 continoues base85 characters without whitespace + "[\\s0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]*" + + "$", + args: ["0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~"], }, ]; } From f5a7db03cd8ab8bf9e7bbd43ec47ae9c57975a37 Mon Sep 17 00:00:00 2001 From: Benedikt Werner <1benediktwerner@gmail.com> Date: Wed, 10 Jun 2020 15:50:26 +0200 Subject: [PATCH 017/111] Base85: Only require 15 continuous base85 chars --- src/core/operations/FromBase85.mjs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/operations/FromBase85.mjs b/src/core/operations/FromBase85.mjs index 9d73baa1..3555b020 100644 --- a/src/core/operations/FromBase85.mjs +++ b/src/core/operations/FromBase85.mjs @@ -38,7 +38,7 @@ class FromBase85 extends Operation { pattern: "^\\s*(?:<~)?" + // Optional whitespace and starting marker "[\\s!-uz]*" + // Any amount of base85 characters and whitespace - "[!-uz]{20}" + // At least 20 continoues base85 characters without whitespace + "[!-uz]{15}" + // At least 15 continoues base85 characters without whitespace "[\\s!-uz]*" + // Any amount of base85 characters and whitespace "(?:~>)?\\s*$", // Optional ending marker and whitespace args: ["!-u"], @@ -47,7 +47,7 @@ class FromBase85 extends Operation { pattern: "^" + "[\\s0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]*" + - "[0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]{20}" + // At least 20 continoues base85 characters without whitespace + "[0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]{15}" + // At least 15 continoues base85 characters without whitespace "[\\s0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]*" + "$", args: ["0-9a-zA-Z.\\-:+=^!/*?&<>()[]{}@%$#"], @@ -56,7 +56,7 @@ class FromBase85 extends Operation { pattern: "^" + "[\\s0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]*" + - "[0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]{20}" + // At least 20 continoues base85 characters without whitespace + "[0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]{15}" + // At least 15 continoues base85 characters without whitespace "[\\s0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]*" + "$", args: ["0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~"], From 3e3c526a625cabeae64d8f3b61f88d326e98473a Mon Sep 17 00:00:00 2001 From: n1073645 Date: Mon, 6 Jul 2020 16:35:14 +0100 Subject: [PATCH 018/111] Caesar Box Cipher Added --- src/core/config/Categories.json | 1 + src/core/operations/CaesarBoxCipher.mjs | 61 ++++++++++++++++++++++ tests/operations/index.mjs | 1 + tests/operations/tests/CaesarBoxCipher.mjs | 45 ++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 src/core/operations/CaesarBoxCipher.mjs create mode 100644 tests/operations/tests/CaesarBoxCipher.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 77e3d319..36465ced 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -91,6 +91,7 @@ "Bacon Cipher Decode", "Bifid Cipher Encode", "Bifid Cipher Decode", + "Caesar Box Cipher", "Affine Cipher Encode", "Affine Cipher Decode", "A1Z26 Cipher Encode", diff --git a/src/core/operations/CaesarBoxCipher.mjs b/src/core/operations/CaesarBoxCipher.mjs new file mode 100644 index 00000000..2e4d9830 --- /dev/null +++ b/src/core/operations/CaesarBoxCipher.mjs @@ -0,0 +1,61 @@ +/** + * @author n1073645 [n1073645@gmail.com] + * @copyright Crown Copyright 2020 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; + +/** + * Caesar Box Cipher operation + */ +class CaesarBoxCipher extends Operation { + + /** + * CaesarBoxCipher constructor + */ + constructor() { + super(); + + this.name = "Caesar Box Cipher"; + this.module = "Ciphers"; + this.description = ""; + this.infoURL = ""; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Box Height", + type: "number", + value: 1 + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const tableHeight = args[0]; + const tableWidth = Math.ceil(input.length / tableHeight); + while (input.indexOf(" ") !== -1) + input = input.replace(" ", ""); + for (let i = 0; i < (tableHeight * tableWidth) - input.length; i++) { + input += "\x00"; + } + let result = ""; + for (let i = 0; i < tableHeight; i++) { + for (let j = i; j < input.length; j += tableHeight) { + if (input.charAt(j) !== "\x00") { + result += input.charAt(j); + } + } + } + return result; + } + +} + +export default CaesarBoxCipher; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 8d3cd623..bd6cd3ed 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -101,6 +101,7 @@ import "./tests/LuhnChecksum.mjs"; import "./tests/CipherSaber2.mjs"; import "./tests/Colossus.mjs"; import "./tests/ParseObjectIDTimestamp.mjs"; +import "./tests/CaesarBoxCipher.mjs"; // Cannot test operations that use the File type yet diff --git a/tests/operations/tests/CaesarBoxCipher.mjs b/tests/operations/tests/CaesarBoxCipher.mjs new file mode 100644 index 00000000..3ccdae66 --- /dev/null +++ b/tests/operations/tests/CaesarBoxCipher.mjs @@ -0,0 +1,45 @@ +/** + * Base58 tests. + * + * @author n1073645 [n1073645@gmail.com] + * + * @copyright Crown Copyright 2020 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Caesar Box Cipher: nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "Caesar Box Cipher", + args: ["1"], + }, + ], + }, + { + name: "Caesar Box Cipher: Hello World!", + input: "Hello World!", + expectedOutput: "Hlodeor!lWl", + recipeConfig: [ + { + op: "Caesar Box Cipher", + args: ["3"], + }, + ], + }, + { + name: "Caesar Box Cipher: Hello World!", + input: "Hlodeor!lWl", + expectedOutput: "HelloWorld!", + recipeConfig: [ + { + op: "Caesar Box Cipher", + args: ["4"], + }, + ], + } +]); From 667dfd820e5e2b93a5daf4258f547d6a0a605a37 Mon Sep 17 00:00:00 2001 From: n1073645 Date: Mon, 6 Jul 2020 16:46:40 +0100 Subject: [PATCH 019/111] info url added --- src/core/operations/CaesarBoxCipher.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/operations/CaesarBoxCipher.mjs b/src/core/operations/CaesarBoxCipher.mjs index 2e4d9830..9c835b4b 100644 --- a/src/core/operations/CaesarBoxCipher.mjs +++ b/src/core/operations/CaesarBoxCipher.mjs @@ -19,8 +19,8 @@ class CaesarBoxCipher extends Operation { this.name = "Caesar Box Cipher"; this.module = "Ciphers"; - this.description = ""; - this.infoURL = ""; + this.description = "Caesar Box Encryption uses a box, a rectangle (or a square), or at least a size W caracterizing its width."; + this.infoURL = "https://www.dcode.fr/caesar-box-cipher"; this.inputType = "string"; this.outputType = "string"; this.args = [ From a7cdb095d23c3af402d02a347fe8fd2b1ede0d0b Mon Sep 17 00:00:00 2001 From: MikeCAT Date: Mon, 4 Oct 2021 22:39:16 +0900 Subject: [PATCH 020/111] Added input validation to fromBase64() --- src/core/lib/Base64.mjs | 45 ++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/core/lib/Base64.mjs b/src/core/lib/Base64.mjs index d9452575..c96e579e 100644 --- a/src/core/lib/Base64.mjs +++ b/src/core/lib/Base64.mjs @@ -95,6 +95,7 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r const output = []; let chr1, chr2, chr3, + encChr1, encChr2, encChr3, encChr4, enc1, enc2, enc3, enc4, i = 0; @@ -103,15 +104,39 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r data = data.replace(re, ""); } - while (i < data.length) { - enc1 = alphabet.indexOf(data.charAt(i++)); - enc2 = alphabet.indexOf(data.charAt(i++) || "="); - enc3 = alphabet.indexOf(data.charAt(i++) || "="); - enc4 = alphabet.indexOf(data.charAt(i++) || "="); + if (data.length % 4 === 1) { + throw new OperationError(`Invalid Base64 input length (${data.length}): it won't be 4n+1`); + } - enc2 = enc2 === -1 ? 64 : enc2; - enc3 = enc3 === -1 ? 64 : enc3; - enc4 = enc4 === -1 ? 64 : enc4; + if (alphabet.length === 65) { + const pad = alphabet.charAt(64); + const padPos = data.indexOf(pad); + if (padPos >= 0) { + // padding character should appear only at the end of the input + // there should be only one or two padding character(s) if it exists + if (padPos < data.length - 2 || data.charAt(data.length - 1) !== pad) { + throw new OperationError("Invalid Base64 input: padding character misused"); + } + if (data.length % 4 !== 0) { + throw new OperationError("Invalid Base64 input: padded not to multiple of 4"); + } + } + } + + while (i < data.length) { + encChr1 = data.charAt(i++); + encChr2 = data.charAt(i++); + encChr3 = data.charAt(i++); + encChr4 = data.charAt(i++); + + enc1 = alphabet.indexOf(encChr1); + enc2 = alphabet.indexOf(encChr2); + enc3 = alphabet.indexOf(encChr3); + enc4 = alphabet.indexOf(encChr4); + + if (enc1 < 0 || enc2 < 0 || enc3 < 0 || enc4 < 0) { + throw new OperationError("Invalid Base64 input: contains non-alphabet char(s)"); + } chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); @@ -119,10 +144,10 @@ export function fromBase64(data, alphabet="A-Za-z0-9+/=", returnType="string", r output.push(chr1); - if (enc3 !== 64) { + if (encChr3 !== "" && enc3 !== 64) { output.push(chr2); } - if (enc4 !== 64) { + if (encChr4 !== "" && enc4 !== 64) { output.push(chr3); } } From e8f91316ffd280715a3e90177a5b04068689883d Mon Sep 17 00:00:00 2001 From: MikeCAT Date: Wed, 20 Oct 2021 21:28:48 +0900 Subject: [PATCH 021/111] Added ROT13/47 Brute Force --- src/core/config/Categories.json | 2 + src/core/operations/ROT13BruteForce.mjs | 102 ++++++++++++++++++++++++ src/core/operations/ROT47BruteForce.mjs | 82 +++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 src/core/operations/ROT13BruteForce.mjs create mode 100644 src/core/operations/ROT47BruteForce.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 09ee8d15..1369267a 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -82,7 +82,9 @@ "RC4", "RC4 Drop", "ROT13", + "ROT13 Brute Force", "ROT47", + "ROT47 Brute Force", "XOR", "XOR Brute Force", "Vigenère Encode", diff --git a/src/core/operations/ROT13BruteForce.mjs b/src/core/operations/ROT13BruteForce.mjs new file mode 100644 index 00000000..bdf9d40a --- /dev/null +++ b/src/core/operations/ROT13BruteForce.mjs @@ -0,0 +1,102 @@ +/** + * @author MikeCAT + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import Utils from "../Utils.mjs"; + +/** + * ROT13 Brute Force operation. + */ +class ROT13BruteForce extends Operation { + + /** + * ROT13BruteForce constructor + */ + constructor() { + super(); + + this.name = "ROT13 Brute Force"; + this.module = "Default"; + this.description = "Try all meaningful amounts for ROT13.

Optionally you can enter your known plaintext (crib) to filter the result."; + this.infoURL = "https://wikipedia.org/wiki/ROT13"; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + name: "Rotate lower case chars", + type: "boolean", + value: true + }, + { + name: "Rotate upper case chars", + type: "boolean", + value: true + }, + { + name: "Rotate numbers", + type: "boolean", + value: false + }, + { + "name": "Sample length", + "type": "number", + "value": 100 + }, + { + "name": "Sample offset", + "type": "number", + "value": 0 + }, + { + "name": "Print amount", + "type": "boolean", + "value": true + }, + { + "name": "Crib (known plaintext string)", + "type": "string", + "value": "" + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [rotateLower, rotateUpper, rotateNum, sampleLength, sampleOffset, printAmount, crib] = args; + const sample = input.slice(sampleOffset, sampleOffset + sampleLength); + const cribLower = crib.toLowerCase(); + const lowerStart = "a".charCodeAt(0), upperStart = "A".charCodeAt(0), numStart = "0".charCodeAt(0); + const result = []; + for (let amount = 1; amount < 26; amount++) { + const rotated = sample.slice(); + for (let i = 0; i < rotated.length; i++) { + if (rotateLower && lowerStart <= rotated[i] && rotated[i] < lowerStart + 26) { + rotated[i] = (rotated[i] - lowerStart + amount) % 26 + lowerStart; + } else if (rotateUpper && upperStart <= rotated[i] && rotated[i] < upperStart + 26) { + rotated[i] = (rotated[i] - upperStart + amount) % 26 + upperStart; + } else if (rotateNum && numStart <= rotated[i] && rotated[i] < numStart + 10) { + rotated[i] = (rotated[i] - numStart + amount) % 10 + numStart; + } + } + const rotatedString = Utils.byteArrayToUtf8(rotated); + if (rotatedString.toLowerCase().indexOf(cribLower) >= 0) { + const rotatedStringPrintable = Utils.printable(rotatedString, false); + if (printAmount) { + const amountStr = "Amount = " + (" " + amount).slice(-2) + ": "; + result.push(amountStr + rotatedStringPrintable); + } else { + result.push(rotatedStringPrintable); + } + } + } + return result.join("\n"); + } +} + +export default ROT13BruteForce; diff --git a/src/core/operations/ROT47BruteForce.mjs b/src/core/operations/ROT47BruteForce.mjs new file mode 100644 index 00000000..5fce5259 --- /dev/null +++ b/src/core/operations/ROT47BruteForce.mjs @@ -0,0 +1,82 @@ +/** + * @author MikeCAT + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import Utils from "../Utils.mjs"; + +/** + * ROT47 Brute Force operation. + */ +class ROT47BruteForce extends Operation { + + /** + * ROT47BruteForce constructor + */ + constructor() { + super(); + + this.name = "ROT47 Brute Force"; + this.module = "Default"; + this.description = "Try all meaningful amounts for ROT47.

Optionally you can enter your known plaintext (crib) to filter the result."; + this.infoURL = "https://wikipedia.org/wiki/ROT13#Variants"; + this.inputType = "byteArray"; + this.outputType = "string"; + this.args = [ + { + "name": "Sample length", + "type": "number", + "value": 100 + }, + { + "name": "Sample offset", + "type": "number", + "value": 0 + }, + { + "name": "Print amount", + "type": "boolean", + "value": true + }, + { + "name": "Crib (known plaintext string)", + "type": "string", + "value": "" + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const [sampleLength, sampleOffset, printAmount, crib] = args; + const sample = input.slice(sampleOffset, sampleOffset + sampleLength); + const cribLower = crib.toLowerCase(); + const result = []; + for (let amount = 1; amount < 94; amount++) { + const rotated = sample.slice(); + for (let i = 0; i < rotated.length; i++) { + if (33 <= rotated[i] && rotated[i] <= 126) { + rotated[i] = (rotated[i] - 33 + amount) % 94 + 33; + } + } + const rotatedString = Utils.byteArrayToUtf8(rotated); + if (rotatedString.toLowerCase().indexOf(cribLower) >= 0) { + const rotatedStringPrintable = Utils.printable(rotatedString, false); + if (printAmount) { + const amountStr = "Amount = " + (" " + amount).slice(-2) + ": "; + result.push(amountStr + rotatedStringPrintable); + } else { + result.push(rotatedStringPrintable); + } + } + } + return result.join("\n"); + } +} + +export default ROT47BruteForce; From 671ae6558fbf773d72bb7519fde7ce1ce203c514 Mon Sep 17 00:00:00 2001 From: Peter Jacobs Date: Fri, 29 Oct 2021 01:31:55 -0500 Subject: [PATCH 022/111] Added 'LZString Decompress' and 'LZString Compress' operations --- package-lock.json | 23 +++++---- package.json | 1 + src/core/config/Categories.json | 4 +- src/core/lib/LZString.mjs | 21 ++++++++ src/core/operations/LZStringCompress.mjs | 55 +++++++++++++++++++++ src/core/operations/LZStringDecompress.mjs | 56 ++++++++++++++++++++++ tests/operations/index.mjs | 1 + tests/operations/tests/LZString.mjs | 33 +++++++++++++ 8 files changed, 184 insertions(+), 10 deletions(-) create mode 100644 src/core/lib/LZString.mjs create mode 100644 src/core/operations/LZStringCompress.mjs create mode 100644 src/core/operations/LZStringDecompress.mjs create mode 100644 tests/operations/tests/LZString.mjs diff --git a/package-lock.json b/package-lock.json index 6fa9016e..d579a3d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2295,9 +2295,9 @@ "dev": true }, "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", "dev": true, "requires": { "delegates": "^1.0.0", @@ -8731,6 +8731,11 @@ "yallist": "^4.0.0" } }, + "lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=" + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -9014,9 +9019,9 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", + "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -12667,9 +12672,9 @@ "dev": true }, "tar": { - "version": "6.1.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.10.tgz", - "integrity": "sha512-kvvfiVvjGMxeUNB6MyYv5z7vhfFRwbwCXJAeL0/lnbrttBVqcMOnpHUf0X42LrPMR8mMpgapkJMchFH4FSHzNA==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", "dev": true, "requires": { "chownr": "^2.0.0", diff --git a/package.json b/package.json index 78a8696b..cf4ceba6 100644 --- a/package.json +++ b/package.json @@ -133,6 +133,7 @@ "lodash": "^4.17.21", "loglevel": "^1.7.1", "loglevel-message-prefix": "^3.0.0", + "lz-string": "^1.4.4", "markdown-it": "^12.2.0", "moment": "^2.29.1", "moment-timezone": "^0.5.33", diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 09ee8d15..fcd4f6af 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -313,7 +313,9 @@ "Bzip2 Decompress", "Bzip2 Compress", "Tar", - "Untar" + "Untar", + "LZString Compress", + "LZString Decompress" ] }, { diff --git a/src/core/lib/LZString.mjs b/src/core/lib/LZString.mjs new file mode 100644 index 00000000..c4919a87 --- /dev/null +++ b/src/core/lib/LZString.mjs @@ -0,0 +1,21 @@ +/** + * lz-string exports. + * + * @author crespyl [peter@crespyl.net] + * @copyright Peter Jacobs 2021 + * @license Apache-2.0 + */ + +import LZString from "lz-string"; + +export const COMPRESSION_OUTPUT_FORMATS = ["default", "UTF16", "Base64"]; +export const COMPRESSION_FUNCTIONS = { + "default": LZString.compress, + "UTF16": LZString.compressToUTF16, + "Base64": LZString.compressToBase64, +}; +export const DECOMPRESSION_FUNCTIONS = { + "default": LZString.decompress, + "UTF16": LZString.decompressFromUTF16, + "Base64": LZString.decompressFromBase64, +}; diff --git a/src/core/operations/LZStringCompress.mjs b/src/core/operations/LZStringCompress.mjs new file mode 100644 index 00000000..11d5710a --- /dev/null +++ b/src/core/operations/LZStringCompress.mjs @@ -0,0 +1,55 @@ +/** + * @author crespyl [peter@crespyl.net] + * @copyright Peter Jacobs 2021 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; + +import {COMPRESSION_OUTPUT_FORMATS, COMPRESSION_FUNCTIONS} from "../lib/LZString.mjs"; + +/** + * LZString Compress operation + */ +class LZStringCompress extends Operation { + + /** + * LZStringCompress constructor + */ + constructor() { + super(); + + this.name = "LZString Compress"; + this.module = "Compression"; + this.description = "Compress the input with lz-string."; + this.infoURL = "https://pieroxy.net/blog/pages/lz-string/index.html"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Compression Format", + type: "option", + defaultIndex: 0, + value: COMPRESSION_OUTPUT_FORMATS + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const compress = COMPRESSION_FUNCTIONS[args[0]]; + if (compress) { + return compress(input); + } else { + throw new OperationError("Unable to find compression function"); + } + } + +} + +export default LZStringCompress; diff --git a/src/core/operations/LZStringDecompress.mjs b/src/core/operations/LZStringDecompress.mjs new file mode 100644 index 00000000..87d0d85b --- /dev/null +++ b/src/core/operations/LZStringDecompress.mjs @@ -0,0 +1,56 @@ +/** + * @author crespyl [peter@crespyl.net] + * @copyright Peter Jacobs 2021 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; + +import {COMPRESSION_OUTPUT_FORMATS, DECOMPRESSION_FUNCTIONS} from "../lib/LZString.mjs"; + +/** + * LZString Decompress operation + */ +class LZStringDecompress extends Operation { + + /** + * LZStringDecompress constructor + */ + constructor() { + super(); + + this.name = "LZString Decompress"; + this.module = "Compression"; + this.description = "Decompresses data that was compressed with lz-string."; + this.infoURL = "https://pieroxy.net/blog/pages/lz-string/index.html"; + this.inputType = "string"; + this.outputType = "string"; + this.args = [ + { + name: "Compression Format", + type: "option", + defaultIndex: 0, + value: COMPRESSION_OUTPUT_FORMATS + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const decompress = DECOMPRESSION_FUNCTIONS[args[0]]; + if (decompress) { + return decompress(input); + } else { + throw new OperationError("Unable to find decompression function"); + } + } + + +} + +export default LZStringDecompress; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 9add20b9..27f0fbb6 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -107,6 +107,7 @@ import "./tests/CBORDecode.mjs"; import "./tests/JA3Fingerprint.mjs"; import "./tests/JA3SFingerprint.mjs"; import "./tests/HASSH.mjs"; +import "./tests/LZString.mjs"; // Cannot test operations that use the File type yet diff --git a/tests/operations/tests/LZString.mjs b/tests/operations/tests/LZString.mjs new file mode 100644 index 00000000..69e47bdd --- /dev/null +++ b/tests/operations/tests/LZString.mjs @@ -0,0 +1,33 @@ +/** + * LZString tests. + * + * @author crespyl [peter@crespyl.net] + * @copyright Peter Jacobs 2021 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "LZString Compress To Base64", + input: "hello world", + expectedOutput: "BYUwNmD2AEDukCcwBMg=", + recipeConfig: [ + { + "op": "LZString Compress", + "args": ["Base64"] + } + ], + }, + { + name: "LZString Decompress From Base64", + input: "BYUwNmD2AEDukCcwBMg=", + expectedOutput: "hello world", + recipeConfig: [ + { + "op": "LZString Decompress", + "args": ["Base64"] + } + ], + } +]); From 1dbcd2ac8499bf37e6e12aef698e01c86f0d61e0 Mon Sep 17 00:00:00 2001 From: CPlusSharp Date: Sun, 7 Nov 2021 11:21:17 +0100 Subject: [PATCH 023/111] PEMtoHex: Support arbitrary PEMs previous implementation only supported some PEMs (e.g. Certificate) the new implementation is more general, it just extracts the base64 between header and footer and decodes that to hex --- src/core/operations/PEMToHex.mjs | 33 ++-- tests/operations/index.mjs | 1 + tests/operations/tests/PEMtoHex.mjs | 294 ++++++++++++++++++++++++++++ 3 files changed, 317 insertions(+), 11 deletions(-) create mode 100644 tests/operations/tests/PEMtoHex.mjs diff --git a/src/core/operations/PEMToHex.mjs b/src/core/operations/PEMToHex.mjs index 095e2c56..575f6f77 100644 --- a/src/core/operations/PEMToHex.mjs +++ b/src/core/operations/PEMToHex.mjs @@ -1,11 +1,14 @@ /** * @author n1474335 [n1474335@gmail.com] + * @author cplussharp * @copyright Crown Copyright 2016 * @license Apache-2.0 */ -import r from "jsrsasign"; +import {fromBase64} from "../lib/Base64.mjs"; import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import Utils from "../Utils.mjs"; /** * PEM to Hex operation @@ -33,17 +36,25 @@ class PEMToHex extends Operation { * @returns {string} */ run(input, args) { - if (input.indexOf("-----BEGIN") < 0) { - // Add header so that the KEYUTIL function works - input = "-----BEGIN CERTIFICATE-----" + input; + let output = ""; + let match; + const regex = /-----BEGIN ([A-Z][A-Z ]+[A-Z])-----/g; + while ((match = regex.exec(input)) !== null) { + // find corresponding end tag + const indexBase64 = match.index + match[0].length; + const footer = `-----END ${match[1]}-----`; + const indexFooter = input.indexOf(footer, indexBase64); + if (indexFooter === -1) { + throw new OperationError(`PEM footer '${footer}' not found`); + } + + // decode base64 content + const base64 = input.substring(indexBase64, indexFooter); + const bytes = fromBase64(base64, "A-Za-z0-9+/=", "byteArray", true); + const hex = bytes.map(b => Utils.hex(b)).join(""); + output += hex; } - if (input.indexOf("-----END") < 0) { - // Add footer so that the KEYUTIL function works - input = input + "-----END CERTIFICATE-----"; - } - const cert = new r.X509(); - cert.readCertPEM(input); - return cert.hex; + return output; } } diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 9add20b9..fede1441 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -66,6 +66,7 @@ import "./tests/PGP.mjs"; import "./tests/PHP.mjs"; import "./tests/ParseIPRange.mjs"; import "./tests/ParseQRCode.mjs"; +import "./tests/PEMtoHex.mjs"; import "./tests/PowerSet.mjs"; import "./tests/Regex.mjs"; import "./tests/Register.mjs"; diff --git a/tests/operations/tests/PEMtoHex.mjs b/tests/operations/tests/PEMtoHex.mjs new file mode 100644 index 00000000..7929bfdd --- /dev/null +++ b/tests/operations/tests/PEMtoHex.mjs @@ -0,0 +1,294 @@ +/** + * Test PEMtoHex with different inputs + * + * @author cplussharp + * + * @license Apache-2.0 + */ + +import TestRegister from "../../lib/TestRegister.mjs"; + +/** RSA 2048bit key pair as PKCS1 and PKCS8 and as certificate */ +const PEMS_RSA_PRIVATE_KEY_PKCS1 = `-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA5WykLKHiBAhmZh5WhocgpQQqZjdrApuRxRT21SJZx6Ce+Oz2 +V17/heozu5LEz63jCxW1NrBckzl/Ys8p9LeqYTu6x/LbKloTjfEWxlzXnzUSqn9J +HIxmmJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDhe2KnMGVDDg6kfCLokDdLo256LeQ4 +CEkViwY6d+at4xDlIHwvZZmG4Smk56eHhvQE3I8sSAzgoLMBamQ5m3MbiULAYtxs +kCpCfjFxrL6Ziaaj7HZoneF40R30KCI9ygF8vkzxLwe3t5Y4XgHL9TYQm1+BDnin +upIB/zTeO1ygBGA66m6zpmkmuG7d8HXIducz+wIDAQABAoIBACQu3jWr0lmQeZXh +cwQEi8F6xrUYSGhA4NyUUdmLcV1ql6fqt29QLDySk1Yh76hRZF17LvlRF0ig6NZM +lfFihhyPrwWZ57bmPe9E9rKSMe+KD0eUi5NVEVk/BmJpzxwZSfRC6NTDz8Zjp7po +FUwGkYlEJdocHlc5N/fcCZG1Jti/Z1AsZIjO6r6S0O7neC7icECBKHUyWa8/yE1N +++TVyMV+z53Ad1PC+SHMGDlbqJAM3o4wAzD/FAIzyVo6GSnnC+bFdgMtIwtwgYTH +rbr8M8j5fqAHTqNJeblqt/5KHEj2VVsIsHIuQ6lv4llESEqmH+N5KE4O33U7/Wmj +y/+VGAECgYEA9ysROHXOx1ofh3tI/r2C2FUan6/AAe4dc+8E4jMGI5T4xeqYHTRV +l1yS+ZKIxqclIoAmd6SJ7Nx2GdQ55MmokZdZRqsFN1flFOZw2kFH/I0zQZXdOjF+ +sf5Lu0FfcTw3VJhJ/YU3CVdlgdP4ekHbaJVFW5i/pTUf5vNs6AGBGxsCgYEA7Z9D +0qnF6GhxA8lJfwnyuktYnwIQoXE6Xp26/NZD7t7HzxHDf43LQxmTk+mDP/yIQHwb +xIx2NE/ncNxlUMl/g1PkJbKVkB8tdIZrLyiT4lebeqgT72Q07IsxRl/GHOr7CfN0 +61OBRCe44IlOtaNAZk4zWwuAwAYx+G8ifuOJ+KECgYBP5NvsJChyx+7pHDC8JwXk +Z53zgBvQg+eBUgGCHHwfhEflsa75wbDo/EOF6JfNnrmiLUpB4i2zIpAKSU9tZMHY +TdPNw/orqX2jA9n2sqNSP1ISIR8hcF5Dqq9QGBGByLUZ4yAHksf3fQiSrrHi0ubZ +J2cD9Jv+Cu4E+Sp61AGngQKBgHmuTPTbq1TP5s+hi9laJsnvO3pxfEKv0MwSyWYf +8rmnq3oGBq6S1buOpVvhAC0MDFm5NB76Lq2rHUFWGyu7g2ik1PfY823SCVzaWJjV +lqUZZ6zv1QWJsvBOdvUqpjC4w8TcvsqjAFb+YFXa+ktZRekdsn607UFn6r7laizA +KC8BAoGAZty7sIGMt1gDaoIjySgOox8x7AlY3QUyNQC5N8KW3MZ8KLC5UBtjhqLy +wYOJr+/1R/7ibiHrKkIE/dmg5QN1iS5tZmFvyLwJ+nHQZObFrlcKtpr+1lekQY/m +ly6YJFk3yj2nhYzt8eVXBX2lCoLG1gsrbpXvUfIGJ53L9m1mVAo= +-----END RSA PRIVATE KEY-----`; + +const PEMS_RSA_PRIVATE_KEY_PKCS8 = `-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDlbKQsoeIECGZm +HlaGhyClBCpmN2sCm5HFFPbVIlnHoJ747PZXXv+F6jO7ksTPreMLFbU2sFyTOX9i +zyn0t6phO7rH8tsqWhON8RbGXNefNRKqf0kcjGaYlDONen1fUP31OP41alEYQiII +UTsl8OF7YqcwZUMODqR8IuiQN0ujbnot5DgISRWLBjp35q3jEOUgfC9lmYbhKaTn +p4eG9ATcjyxIDOCgswFqZDmbcxuJQsBi3GyQKkJ+MXGsvpmJpqPsdmid4XjRHfQo +Ij3KAXy+TPEvB7e3ljheAcv1NhCbX4EOeKe6kgH/NN47XKAEYDrqbrOmaSa4bt3w +dch25zP7AgMBAAECggEAJC7eNavSWZB5leFzBASLwXrGtRhIaEDg3JRR2YtxXWqX +p+q3b1AsPJKTViHvqFFkXXsu+VEXSKDo1kyV8WKGHI+vBZnntuY970T2spIx74oP +R5SLk1URWT8GYmnPHBlJ9ELo1MPPxmOnumgVTAaRiUQl2hweVzk399wJkbUm2L9n +UCxkiM7qvpLQ7ud4LuJwQIEodTJZrz/ITU375NXIxX7PncB3U8L5IcwYOVuokAze +jjADMP8UAjPJWjoZKecL5sV2Ay0jC3CBhMetuvwzyPl+oAdOo0l5uWq3/kocSPZV +Wwiwci5DqW/iWURISqYf43koTg7fdTv9aaPL/5UYAQKBgQD3KxE4dc7HWh+He0j+ +vYLYVRqfr8AB7h1z7wTiMwYjlPjF6pgdNFWXXJL5kojGpyUigCZ3pIns3HYZ1Dnk +yaiRl1lGqwU3V+UU5nDaQUf8jTNBld06MX6x/ku7QV9xPDdUmEn9hTcJV2WB0/h6 +QdtolUVbmL+lNR/m82zoAYEbGwKBgQDtn0PSqcXoaHEDyUl/CfK6S1ifAhChcTpe +nbr81kPu3sfPEcN/jctDGZOT6YM//IhAfBvEjHY0T+dw3GVQyX+DU+QlspWQHy10 +hmsvKJPiV5t6qBPvZDTsizFGX8Yc6vsJ83TrU4FEJ7jgiU61o0BmTjNbC4DABjH4 +byJ+44n4oQKBgE/k2+wkKHLH7ukcMLwnBeRnnfOAG9CD54FSAYIcfB+ER+WxrvnB +sOj8Q4Xol82euaItSkHiLbMikApJT21kwdhN083D+iupfaMD2fayo1I/UhIhHyFw +XkOqr1AYEYHItRnjIAeSx/d9CJKuseLS5tknZwP0m/4K7gT5KnrUAaeBAoGAea5M +9NurVM/mz6GL2Vomye87enF8Qq/QzBLJZh/yuaeregYGrpLVu46lW+EALQwMWbk0 +HvourasdQVYbK7uDaKTU99jzbdIJXNpYmNWWpRlnrO/VBYmy8E529SqmMLjDxNy+ +yqMAVv5gVdr6S1lF6R2yfrTtQWfqvuVqLMAoLwECgYBm3LuwgYy3WANqgiPJKA6j +HzHsCVjdBTI1ALk3wpbcxnwosLlQG2OGovLBg4mv7/VH/uJuIesqQgT92aDlA3WJ +Lm1mYW/IvAn6cdBk5sWuVwq2mv7WV6RBj+aXLpgkWTfKPaeFjO3x5VcFfaUKgsbW +Cytule9R8gYnncv2bWZUCg== +-----END PRIVATE KEY-----`; + +const PEMS_RSA_PUBLIC_KEY_PKCS1 = `-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEA5WykLKHiBAhmZh5WhocgpQQqZjdrApuRxRT21SJZx6Ce+Oz2V17/ +heozu5LEz63jCxW1NrBckzl/Ys8p9LeqYTu6x/LbKloTjfEWxlzXnzUSqn9JHIxm +mJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDhe2KnMGVDDg6kfCLokDdLo256LeQ4CEkV +iwY6d+at4xDlIHwvZZmG4Smk56eHhvQE3I8sSAzgoLMBamQ5m3MbiULAYtxskCpC +fjFxrL6Ziaaj7HZoneF40R30KCI9ygF8vkzxLwe3t5Y4XgHL9TYQm1+BDninupIB +/zTeO1ygBGA66m6zpmkmuG7d8HXIducz+wIDAQAB +-----END RSA PUBLIC KEY-----`; + +const PEMS_RSA_PUBLIC_KEY_PKCS8 = `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5WykLKHiBAhmZh5Whocg +pQQqZjdrApuRxRT21SJZx6Ce+Oz2V17/heozu5LEz63jCxW1NrBckzl/Ys8p9Leq +YTu6x/LbKloTjfEWxlzXnzUSqn9JHIxmmJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDh +e2KnMGVDDg6kfCLokDdLo256LeQ4CEkViwY6d+at4xDlIHwvZZmG4Smk56eHhvQE +3I8sSAzgoLMBamQ5m3MbiULAYtxskCpCfjFxrL6Ziaaj7HZoneF40R30KCI9ygF8 +vkzxLwe3t5Y4XgHL9TYQm1+BDninupIB/zTeO1ygBGA66m6zpmkmuG7d8HXIducz ++wIDAQAB +-----END PUBLIC KEY-----`; + +const PEMS_RSA_CERT = `-----BEGIN CERTIFICATE----- +MIIDGzCCAgOgAwIBAgIUROs52CB3BsvEVLOCtALalnJG8tEwDQYJKoZIhvcNAQEL +BQAwHTEbMBkGA1UEAwwSUlNBIDIwNDggUHVibGljS2V5MB4XDTIxMDQxMzIxMDE0 +OVoXDTMxMDQxMTIxMDE0OVowHTEbMBkGA1UEAwwSUlNBIDIwNDggUHVibGljS2V5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5WykLKHiBAhmZh5Whocg +pQQqZjdrApuRxRT21SJZx6Ce+Oz2V17/heozu5LEz63jCxW1NrBckzl/Ys8p9Leq +YTu6x/LbKloTjfEWxlzXnzUSqn9JHIxmmJQzjXp9X1D99Tj+NWpRGEIiCFE7JfDh +e2KnMGVDDg6kfCLokDdLo256LeQ4CEkViwY6d+at4xDlIHwvZZmG4Smk56eHhvQE +3I8sSAzgoLMBamQ5m3MbiULAYtxskCpCfjFxrL6Ziaaj7HZoneF40R30KCI9ygF8 +vkzxLwe3t5Y4XgHL9TYQm1+BDninupIB/zTeO1ygBGA66m6zpmkmuG7d8HXIducz ++wIDAQABo1MwUTAdBgNVHQ4EFgQUcRhRB6H5JqlDHbymwqydW2/EAt8wHwYDVR0j +BBgwFoAUcRhRB6H5JqlDHbymwqydW2/EAt8wDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQsFAAOCAQEALXBmDizTp/Uz4M2A4nCl0AVclrXEk+YjAKqZnvtj44Gs +CUcpxtcXu64ppsSYCwawvzIm6B2Mdmib422aInH0e0oNrn8cRzC144Hjnzxguamj +LyZXnH/0wN9SAjqCKt++urH9wbRMIl0v+g4CWjGyY+eYkMmd1UMQvdCCCv6RVm56 +7dBCijJIHg23JbgPJD72JCluXtTYWllv3duSwuWeYHo5EftU456pDcztkgn9XwFk +PFGnHLmbjpSzjE7u29qCjwHl3CiUsjfUlYFl/mf27oDXPqaWqPYv3fWH3H3ymiZQ +cqptUF4hDtPkaNkKWFmlljChN92o8g/jrv4DVDgJzQ== +-----END CERTIFICATE-----`; + +/** EC P-256 key pair and certificate */ +const PEMS_EC_P256_PRIVATE_KEY = `-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIIhdQxQIcMnCHD3X4WqNv+VgycWmFoEZpRl9X0+dT9uHoAoGCCqGSM49 +AwEHoUQDQgAEFLQcBbzDweo6af4k3k0gKWMNWOZVn8+9hH2rv4DKKYZ7E1z64LBt +PnB1gMz++HDKySr2ozD3/46dIbQMXUZKpw== +-----END EC PRIVATE KEY-----`; + +const PEMS_EC_P256_PRIVATE_KEY_PKCS8 = `-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgiF1DFAhwycIcPdfh +ao2/5WDJxaYWgRmlGX1fT51P24ehRANCAAQUtBwFvMPB6jpp/iTeTSApYw1Y5lWf +z72Efau/gMophnsTXPrgsG0+cHWAzP74cMrJKvajMPf/jp0htAxdRkqn +-----END PRIVATE KEY-----`; + +const PEMS_EC_P256_PUBLIC_KEY = `-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFLQcBbzDweo6af4k3k0gKWMNWOZV +n8+9hH2rv4DKKYZ7E1z64LBtPnB1gMz++HDKySr2ozD3/46dIbQMXUZKpw== +-----END PUBLIC KEY-----`; + +const PEMS_FOO = `-----BEGIN FOO----- +Rk9P +-----END FOO-----`; +const PEMS_BAR = `-----BEGIN BAR----- +QkFS +-----END BAR-----`; + +TestRegister.addTests([ + { + name: "PEMtoHex: Nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + } + ] + }, + { + name: "PEMtoHex: No footer", + input: PEMS_RSA_PRIVATE_KEY_PKCS1.substr(0, 200), + expectedOutput: "PEM footer '-----END RSA PRIVATE KEY-----' not found", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + } + ] + }, + { + name: "PEMtoHex: Multiple PEMs", + input: PEMS_FOO + '\n' + PEMS_BAR, + expectedOutput: "FOOBAR", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "From Hex", + "args": ["None"] + } + ] + }, + { + name: "PEMtoHex: Single line PEM", + input: PEMS_FOO.replace(/(\n|\r)/gm,""), + expectedOutput: "FOO", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "From Hex", + "args": ["None"] + } + ] + }, + { + name: "PEMtoHex: EC P-256 Private Key", + input: PEMS_EC_P256_PRIVATE_KEY, + expectedOutput: "30770201010420885d43140870c9c21c3dd7e16a8dbfe560c9c5a6168119a5197d5f4f9d4fdb87a00a06082a8648ce3d030107a1440342000414b41c05bcc3c1ea3a69fe24de4d2029630d58e6559fcfbd847dabbf80ca29867b135cfae0b06d3e707580ccfef870cac92af6a330f7ff8e9d21b40c5d464aa7", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + } + ] + }, + { + name: "PEMtoHex: EC P-256 Private Key PKCS8", + input: PEMS_EC_P256_PRIVATE_KEY_PKCS8, + expectedOutput: "308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420885d43140870c9c21c3dd7e16a8dbfe560c9c5a6168119a5197d5f4f9d4fdb87a1440342000414b41c05bcc3c1ea3a69fe24de4d2029630d58e6559fcfbd847dabbf80ca29867b135cfae0b06d3e707580ccfef870cac92af6a330f7ff8e9d21b40c5d464aa7", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + } + ] + }, + { + name: "PEMtoHex: EC P-256 Public Key", + input: PEMS_EC_P256_PUBLIC_KEY, + expectedOutput: "3059301306072a8648ce3d020106082a8648ce3d0301070342000414b41c05bcc3c1ea3a69fe24de4d2029630d58e6559fcfbd847dabbf80ca29867b135cfae0b06d3e707580ccfef870cac92af6a330f7ff8e9d21b40c5d464aa7", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + } + ] + }, + { + name: "PEMtoHex: RSA Private Key PKCS1", + input: PEMS_RSA_PRIVATE_KEY_PKCS1, + expectedOutput: "fb49bd96ffc5d1351a35d773921fac03", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "MD5", + "args": [] + } + ] + }, + { + name: "PEMtoHex: RSA Private Key PKCS8", + input: PEMS_RSA_PRIVATE_KEY_PKCS8, + expectedOutput: "23086d03633689fee64680c3c24409eb", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "MD5", + "args": [] + } + ] + }, + { + name: "PEMtoHex: RSA Public Key PKCS1", + input: PEMS_RSA_PUBLIC_KEY_PKCS1, + expectedOutput: "5fc3f1f6c5d5806760b12eaad0c0292c", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "MD5", + "args": [] + } + ] + }, + { + name: "PEMtoHex: RSA Public Key PKCS8", + input: PEMS_RSA_PUBLIC_KEY_PKCS8, + expectedOutput: "30fbe8e9495d591232affebdd6206ea6", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "MD5", + "args": [] + } + ] + }, + { + name: "PEMtoHex: Certificate", + input: PEMS_RSA_CERT, + expectedOutput: "6694d8ca4a0ceb84c3951d25dc05ec6e", + recipeConfig: [ + { + "op": "PEM to Hex", + "args": [] + }, + { + "op": "MD5", + "args": [] + } + ] + } +]); From b7a978505f8ea4f4d98dc5f166875db80bef0d8e Mon Sep 17 00:00:00 2001 From: CPlusSharp Date: Wed, 17 Nov 2021 20:19:42 +0100 Subject: [PATCH 024/111] PEMToHex: add magic check so it gets found --- src/core/operations/PEMToHex.mjs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/core/operations/PEMToHex.mjs b/src/core/operations/PEMToHex.mjs index 575f6f77..1c42d6a9 100644 --- a/src/core/operations/PEMToHex.mjs +++ b/src/core/operations/PEMToHex.mjs @@ -28,6 +28,12 @@ class PEMToHex extends Operation { this.inputType = "string"; this.outputType = "string"; this.args = []; + this.checks = [ + { + "pattern": "----BEGIN ([A-Z][A-Z ]+[A-Z])-----", + "args": [] + } + ]; } /** From 2574a63975ecced6e066ae673a986ad87394b7db Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Wed, 29 Dec 2021 19:32:39 +0000 Subject: [PATCH 025/111] Minor adjustments --- src/core/lib/Binary.mjs | 26 ++++++++++++---------- src/core/operations/ToUpperCase.mjs | 34 ++++++++++++++--------------- 2 files changed, 31 insertions(+), 29 deletions(-) diff --git a/src/core/lib/Binary.mjs b/src/core/lib/Binary.mjs index dc63fc58..56db4c2a 100644 --- a/src/core/lib/Binary.mjs +++ b/src/core/lib/Binary.mjs @@ -19,27 +19,29 @@ import OperationError from "../errors/OperationError.mjs"; * @returns {string} * * @example - * // returns "00010000 00100000 00110000" + * // returns "00001010 00010100 00011110" * toBinary([10,20,30]); * - * // returns "00010000 00100000 00110000" - * toBinary([10,20,30], ":"); + * // returns "00001010:00010100:00011110" + * toBinary([10,20,30], "Colon"); + * + * // returns "1010:10100:11110" + * toBinary([10,20,30], "Colon", 0); */ export function toBinary(data, delim="Space", padding=8) { - if (!data) return ""; + if (!data) throw new OperationError("Empty input data enocuntered"); delim = Utils.charRep(delim); let output = ""; - for (let i = 0; i < data.length; i++) { - output += data[i].toString(2).padStart(padding, "0") + delim; + output += data[i].toString(2).padStart(padding, "0"); + if (i !== data.length - 1) output += delim; } - if (delim.length) { - return output.slice(0, -delim.length); - } else { - return output; + // Remove the delimiter from the end of the string. + output = output.slice(0, -delim.length); } + return output; } @@ -53,10 +55,10 @@ export function toBinary(data, delim="Space", padding=8) { * * @example * // returns [10,20,30] - * fromBinary("00010000 00100000 00110000"); + * fromBinary("00001010 00010100 00011110"); * * // returns [10,20,30] - * fromBinary("00010000:00100000:00110000", "Colon"); + * fromBinary("00001010:00010100:00011110", "Colon"); */ export function fromBinary(data, delim="Space", byteLen=8) { if (byteLen < 1 || Math.round(byteLen) !== byteLen) diff --git a/src/core/operations/ToUpperCase.mjs b/src/core/operations/ToUpperCase.mjs index 0bc9b5a9..eb0e315a 100644 --- a/src/core/operations/ToUpperCase.mjs +++ b/src/core/operations/ToUpperCase.mjs @@ -38,23 +38,23 @@ class ToUpperCase extends Operation { */ run(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(); + if (scope === "All") { + return input.toUpperCase(); + } + const scopeRegex = { + "Word": /(\b\w)/gi, + "Sentence": /(?:\.|^)\s*(\b\w)/gi, + "Paragraph": /(?:\n|^)\s*(\b\w)/gi + }[ scope ]; + if (scopeRegex !== undefined) { + // Use the regexes to capitalize the input. + return input.replace(scopeRegex, function(m) { + return m.toUpperCase(); + }); + } + else { + // The selected scope was invalid. + throw new OperationError("Unrecognized capitalization scope"); } } From ed542582f96541dd90fde52e4f0f07a9b6427ca6 Mon Sep 17 00:00:00 2001 From: Michael Rowley Date: Wed, 29 Dec 2021 19:59:48 +0000 Subject: [PATCH 026/111] Added more error-handling to ToUpperCase() --- src/core/operations/ToUpperCase.mjs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/core/operations/ToUpperCase.mjs b/src/core/operations/ToUpperCase.mjs index eb0e315a..08ffce87 100644 --- a/src/core/operations/ToUpperCase.mjs +++ b/src/core/operations/ToUpperCase.mjs @@ -37,6 +37,9 @@ class ToUpperCase extends Operation { * @returns {string} */ run(input, args) { + if (!args || args.length === 0) { + throw new OperationException("No capitalization scope was provided."); + } const scope = args[0]; if (scope === "All") { return input.toUpperCase(); From 578a61d33122d935557777b4dea38a6a27789a56 Mon Sep 17 00:00:00 2001 From: Robin Scholtes Date: Mon, 17 Jan 2022 23:37:24 +1300 Subject: [PATCH 027/111] add cetacean cipher encoder and decoder operations, tests. Update .gitignore to exclude idea generated files --- .gitignore | 3 + src/core/config/Categories.json | 2 + src/core/operations/CetaceanCipherDecode.mjs | 64 +++++++++++++++++++ src/core/operations/CetaceanCipherEncode.mjs | 54 ++++++++++++++++ tests/operations/index.mjs | 2 + .../operations/tests/CetaceanCipherDecode.mjs | 22 +++++++ .../operations/tests/CetaceanCipherEncode.mjs | 22 +++++++ 7 files changed, 169 insertions(+) create mode 100644 src/core/operations/CetaceanCipherDecode.mjs create mode 100644 src/core/operations/CetaceanCipherEncode.mjs create mode 100644 tests/operations/tests/CetaceanCipherDecode.mjs create mode 100644 tests/operations/tests/CetaceanCipherEncode.mjs diff --git a/.gitignore b/.gitignore index 40682646..a2aa99a3 100755 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ src/node/index.mjs **/*.DS_Store tests/browser/output/* +# ide +.idea +*.iml diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 09ee8d15..8f05d4c9 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -75,6 +75,8 @@ "Blowfish Decrypt", "DES Encrypt", "DES Decrypt", + "Cetacean Cipher Encode", + "Cetacean Cipher Decode", "Triple DES Encrypt", "Triple DES Decrypt", "RC2 Encrypt", diff --git a/src/core/operations/CetaceanCipherDecode.mjs b/src/core/operations/CetaceanCipherDecode.mjs new file mode 100644 index 00000000..a79b98c5 --- /dev/null +++ b/src/core/operations/CetaceanCipherDecode.mjs @@ -0,0 +1,64 @@ +/** + * @author dolphinOnKeys [robin@weird.io] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; + +/** + * Cetacean Cipher Decode operation + */ +class CetaceanCipherDecode extends Operation { + + /** + * CetaceanCipherDecode constructor + */ + constructor() { + super(); + + this.name = "Cetacean Cipher Decode"; + this.module = "Ciphers"; + this.description = "Decode Cetacean Cipher input.

e.g. EEEEEEEEEeeEeEEEEEEEEEEEEeeEeEEe becomes hi"; + this.infoURL = ""; + this.inputType = "string"; + this.outputType = "string"; + + this.checks = [ + { + pattern: "^(?:[eE]{16,})(?: [eE]{16,})*$", + flags: "", + args: [] + } + ] + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + const binaryArray = []; + for ( const char of input ) { + if ( char === ' ' ) { + binaryArray.push(...[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 ]); + } else { + binaryArray.push( char === 'e' ? 1 : 0 ); + } + } + + const byteArray = []; + + for ( let i = 0; i < binaryArray.length; i += 16 ) { + byteArray.push(binaryArray.slice(i, i + 16).join('')) + } + + return byteArray.map( byte => + String.fromCharCode(parseInt( byte , 2 ) + ) + ).join(''); + } +} + +export default CetaceanCipherDecode; diff --git a/src/core/operations/CetaceanCipherEncode.mjs b/src/core/operations/CetaceanCipherEncode.mjs new file mode 100644 index 00000000..e32e4f81 --- /dev/null +++ b/src/core/operations/CetaceanCipherEncode.mjs @@ -0,0 +1,54 @@ +/** + * @author dolphinOnKeys [robin@weird.io] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; + +/** + * Cetacean Cipher Encode operation + */ +class CetaceanCipherEncode extends Operation { + + /** + * CetaceanCipherEncode constructor + */ + constructor() { + super(); + + this.name = "Cetacean Cipher Encode"; + this.module = "Ciphers"; + this.description = "Converts any input into Cetacean Cipher.

e.g. hi becomes EEEEEEEEEeeEeEEEEEEEEEEEEeeEeEEe\""; + this.infoURL = ""; + this.inputType = "string"; + this.outputType = "string"; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run(input, args) { + let result = []; + let charArray = input.split(''); + + charArray.map( ( character ) => { + if ( character === ' ' ) { + result.push( character ); + } else { + const binaryArray = this.encodeToBinary( character ).split(''); + result.push( binaryArray.map(( str ) => str === '1' ? 'e' : 'E' ).join('')); + } + }); + + return result.join(''); + } + + encodeToBinary( char, padding = 16 ) { + return char.charCodeAt(0).toString(2).padStart( padding, '0'); + } +} + +export default CetaceanCipherEncode; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 9add20b9..5200e3a1 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -26,6 +26,8 @@ import "./tests/Base62.mjs"; import "./tests/BitwiseOp.mjs"; import "./tests/ByteRepr.mjs"; import "./tests/CartesianProduct.mjs"; +import "./tests/CetaceanCipherEncode.mjs"; +import "./tests/CetaceanCipherDecode.mjs"; import "./tests/CharEnc.mjs"; import "./tests/ChangeIPFormat.mjs"; import "./tests/Charts.mjs"; diff --git a/tests/operations/tests/CetaceanCipherDecode.mjs b/tests/operations/tests/CetaceanCipherDecode.mjs new file mode 100644 index 00000000..e834dc1e --- /dev/null +++ b/tests/operations/tests/CetaceanCipherDecode.mjs @@ -0,0 +1,22 @@ +/** + * CetaceanCipher Encode tests + * + * @author dolphinOnKeys + * @copyright Crown Copyright 2022 + * @licence Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Cetacean Cipher Decode", + input: "EEEEEEEEEeeEEEEe EEEEEEEEEeeEEEeE EEEEEEEEEeeEEEee EEeeEEEEEeeEEeee", + expectedOutput: "a b c で", + recipeConfig: [ + { + op: "Cetacean Cipher Decode", + args: [] + }, + ], + } +]); diff --git a/tests/operations/tests/CetaceanCipherEncode.mjs b/tests/operations/tests/CetaceanCipherEncode.mjs new file mode 100644 index 00000000..bef76388 --- /dev/null +++ b/tests/operations/tests/CetaceanCipherEncode.mjs @@ -0,0 +1,22 @@ +/** + * CetaceanCipher Encode tests + * + * @author dolphinOnKeys + * @copyright Crown Copyright 2022 + * @licence Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Cetacean Cipher Encode", + input: "a b c で", + expectedOutput: "EEEEEEEEEeeEEEEe EEEEEEEEEeeEEEeE EEEEEEEEEeeEEEee EEeeEEEEEeeEEeee", + recipeConfig: [ + { + op: "Cetacean Cipher Encode", + args: [] + }, + ], + } +]); From add745551b0d1ff8e58bc9f05f6f2c157c34cbb6 Mon Sep 17 00:00:00 2001 From: John L Date: Fri, 11 Feb 2022 16:56:58 +0000 Subject: [PATCH 028/111] WIP --- tests/browser/ops.js | 53 +++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/tests/browser/ops.js b/tests/browser/ops.js index 8d23cabd..8aa5e7ad 100644 --- a/tests/browser/ops.js +++ b/tests/browser/ops.js @@ -6,6 +6,9 @@ * @license Apache-2.0 */ +// import Images from "../operations/samples/Images.mjs"; +const Images = import("../operations/samples/Images.mjs"); + module.exports = { before: browser => { browser @@ -44,42 +47,42 @@ module.exports = { // testOp(browser, "Bifid Cipher Encode", "test input", "test_output"); // testOp(browser, "Bit shift left", "test input", "test_output"); // testOp(browser, "Bit shift right", "test input", "test_output"); - // testOp(browser, "Blowfish Decrypt", "test input", "test_output"); - // testOp(browser, "Blowfish Encrypt", "test input", "test_output"); - // testOp(browser, "Blur Image", "test input", "test_output"); + testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]); + testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); + testOp(browser, "Blur Image", Images.PNG_HEX, "test_output"); // testOp(browser, "Bombe", "test input", "test_output"); - // testOp(browser, "Bzip2 Compress", "test input", "test_output"); - // testOp(browser, "Bzip2 Decompress", "test input", "test_output"); - // testOp(browser, "CRC-16 Checksum", "test input", "test_output"); - // testOp(browser, "CRC-32 Checksum", "test input", "test_output"); - // testOp(browser, "CRC-8 Checksum", "test input", "test_output"); - // testOp(browser, "CSS Beautify", "test input", "test_output"); - // testOp(browser, "CSS Minify", "test input", "test_output"); - // testOp(browser, "CSS selector", "test input", "test_output"); + testOp(browser, "Bzip2 Compress", "test input", "test_output"); + testOp(browser, "Bzip2 Decompress", "test input", "test_output"); + testOp(browser, "CRC-16 Checksum", "test input", "test_output"); + testOp(browser, "CRC-32 Checksum", "test input", "test_output"); + testOp(browser, "CRC-8 Checksum", "test input", "test_output"); + testOp(browser, "CSS Beautify", "test input", "test_output"); + testOp(browser, "CSS Minify", "test input", "test_output"); + testOp(browser, "CSS selector", "test input", "test_output"); // testOp(browser, "CSV to JSON", "test input", "test_output"); - // testOp(browser, "CTPH", "test input", "test_output"); + testOp(browser, "CTPH", "test input", "test_output"); // testOp(browser, "Cartesian Product", "test input", "test_output"); // testOp(browser, "Change IP format", "test input", "test_output"); - // testOp(browser, "Chi Square", "test input", "test_output"); + testOp(browser, "Chi Square", "test input", "test_output"); // testOp(browser, "CipherSaber2 Decrypt", "test input", "test_output"); // testOp(browser, "CipherSaber2 Encrypt", "test input", "test_output"); // testOp(browser, "Citrix CTX1 Decode", "test input", "test_output"); // testOp(browser, "Citrix CTX1 Encode", "test input", "test_output"); // testOp(browser, "Colossus", "test input", "test_output"); // testOp(browser, "Comment", "test input", "test_output"); - // testOp(browser, "Compare CTPH hashes", "test input", "test_output"); - // testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); - // testOp(browser, "Conditional Jump", "test input", "test_output"); - // testOp(browser, "Contain Image", "test input", "test_output"); - // testOp(browser, "Convert area", "test input", "test_output"); - // testOp(browser, "Convert co-ordinate format", "test input", "test_output"); - // testOp(browser, "Convert data units", "test input", "test_output"); - // testOp(browser, "Convert distance", "test input", "test_output"); + testOp(browser, "Compare CTPH hashes", "test input", "test_output"); + testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); + // /testOp(browser, "Conditional Jump", "test input", "test_output"); + testOp(browser, "Contain Image", "test input", "test_output"); + testOp(browser, "Convert area", "test input", "test_output"); + // /testOp(browser, "Convert co-ordinate format", "test input", "test_output"); + testOp(browser, "Convert data units", "test input", "test_output"); + testOp(browser, "Convert distance", "test input", "test_output"); // testOp(browser, "Convert Image Format", "test input", "test_output"); - // testOp(browser, "Convert mass", "test input", "test_output"); - // testOp(browser, "Convert speed", "test input", "test_output"); - // testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); - // testOp(browser, "Count occurrences", "test input", "test_output"); + testOp(browser, "Convert mass", "test input", "test_output"); + testOp(browser, "Convert speed", "test input", "test_output"); + // /testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); + testOp(browser, "Count occurrences", "test input", "test_output"); // testOp(browser, "Cover Image", "test input", "test_output"); // testOp(browser, "Crop Image", "test input", "test_output"); // testOp(browser, "DES Decrypt", "test input", "test_output"); From 92767b107879b9611dc3d30b0c5db413a3858753 Mon Sep 17 00:00:00 2001 From: John L Date: Thu, 31 Mar 2022 19:32:41 +0100 Subject: [PATCH 029/111] Try import --- package-lock.json | 40 +- package.json | 2 +- tests/browser/ops.js | 799 +++++++++++++++------------- tests/operations/samples/Images.mjs | 6 + 4 files changed, 467 insertions(+), 380 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4b8579b6..e4feff32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -99,7 +99,7 @@ "babel-eslint": "^10.1.0", "babel-loader": "^8.2.2", "babel-plugin-dynamic-import-node": "^2.3.3", - "chromedriver": "^97.0.1", + "chromedriver": "^98.0.1", "cli-progress": "^3.9.0", "colors": "^1.4.0", "copy-webpack-plugin": "^9.0.1", @@ -4398,9 +4398,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001251", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", - "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==", + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", "dev": true, "funding": { "type": "opencollective", @@ -4474,7 +4474,7 @@ "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "deprecated": "Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies", "dev": true, "dependencies": { "anymatch": "^2.0.0", @@ -4625,9 +4625,9 @@ } }, "node_modules/chromedriver": { - "version": "97.0.2", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-97.0.2.tgz", - "integrity": "sha512-sOAfKCR3WsHvmKedZoWa+3tBVGdPtxq4zKxgKZCoJ2c924olBTW4Bnha6SHl93Yo7+QqsNn6ZpAC0ojhutacAg==", + "version": "98.0.1", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-98.0.1.tgz", + "integrity": "sha512-/04KkHHE/K/lfwdPTQr5fxi1dWvM83p8T/IkYbyGK2PBlH7K49Dd71A9jrS+aWgXlZYkuHhbwiy2PA2QqZ5qQw==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -7411,9 +7411,9 @@ } }, "node_modules/extract-zip/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -21682,9 +21682,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001251", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", - "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==", + "version": "1.0.30001312", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", + "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", "dev": true }, "caseless": { @@ -21869,9 +21869,9 @@ "dev": true }, "chromedriver": { - "version": "97.0.2", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-97.0.2.tgz", - "integrity": "sha512-sOAfKCR3WsHvmKedZoWa+3tBVGdPtxq4zKxgKZCoJ2c924olBTW4Bnha6SHl93Yo7+QqsNn6ZpAC0ojhutacAg==", + "version": "98.0.1", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-98.0.1.tgz", + "integrity": "sha512-/04KkHHE/K/lfwdPTQr5fxi1dWvM83p8T/IkYbyGK2PBlH7K49Dd71A9jrS+aWgXlZYkuHhbwiy2PA2QqZ5qQw==", "dev": true, "requires": { "@testim/chrome-version": "^1.1.2", @@ -24109,9 +24109,9 @@ }, "dependencies": { "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dev": true, "requires": { "ms": "2.1.2" diff --git a/package.json b/package.json index 8e7c1a2a..96d40c19 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "babel-eslint": "^10.1.0", "babel-loader": "^8.2.2", "babel-plugin-dynamic-import-node": "^2.3.3", - "chromedriver": "^97.0.1", + "chromedriver": "^98.0.1", "cli-progress": "^3.9.0", "colors": "^1.4.0", "copy-webpack-plugin": "^9.0.1", diff --git a/tests/browser/ops.js b/tests/browser/ops.js index 8aa5e7ad..49e7c63a 100644 --- a/tests/browser/ops.js +++ b/tests/browser/ops.js @@ -6,9 +6,6 @@ * @license Apache-2.0 */ -// import Images from "../operations/samples/Images.mjs"; -const Images = import("../operations/samples/Images.mjs"); - module.exports = { before: browser => { browser @@ -20,353 +17,367 @@ module.exports = { }, "Sanity check operations": browser => { - testOp(browser, "A1Z26 Cipher Decode", "20 5 19 20 15 21 20 16 21 20", "testoutput"); - testOp(browser, "A1Z26 Cipher Encode", "test input", "20 5 19 20 9 14 16 21 20"); - testOp(browser, "ADD", "test input", "Ê»ÉÊv¿ÄÆËÊ", [{ "option": "Hex", "string": "56" }]); - testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }]); - testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]); - testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]); - testOp(browser, "Add line numbers", "test input", "1 test input"); - // testOp(browser, "Add Text To Image", "test input", "test_output"); - testOp(browser, "Adler-32 Checksum", "test input", "16160411"); - testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]); - testOp(browser, "Affine Cipher Encode", "test input", "njln rbfpn", [2, 1]); - testOp(browser, "Analyse hash", "0123456789abcdef", /CRC-64/); - testOp(browser, "Atbash Cipher", "test input", "gvhg rmkfg"); - // testOp(browser, "Avro to JSON", "test input", "test_output"); - // testOp(browser, "BLAKE2b", "test input", "test_output"); - // testOp(browser, "BLAKE2s", "test input", "test_output"); - // testOp(browser, "BSON deserialise", "test input", "test_output"); - // testOp(browser, "BSON serialise", "test input", "test_output"); - // testOp(browser, "Bacon Cipher Decode", "test input", "test_output"); - // testOp(browser, "Bacon Cipher Encode", "test input", "test_output"); - // testOp(browser, "Bcrypt", "test input", "test_output"); - // testOp(browser, "Bcrypt compare", "test input", "test_output"); - // testOp(browser, "Bcrypt parse", "test input", "test_output"); - // testOp(browser, "Bifid Cipher Decode", "test input", "test_output"); - // testOp(browser, "Bifid Cipher Encode", "test input", "test_output"); - // testOp(browser, "Bit shift left", "test input", "test_output"); - // testOp(browser, "Bit shift right", "test input", "test_output"); - testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]); - testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); - testOp(browser, "Blur Image", Images.PNG_HEX, "test_output"); - // testOp(browser, "Bombe", "test input", "test_output"); - testOp(browser, "Bzip2 Compress", "test input", "test_output"); - testOp(browser, "Bzip2 Decompress", "test input", "test_output"); - testOp(browser, "CRC-16 Checksum", "test input", "test_output"); - testOp(browser, "CRC-32 Checksum", "test input", "test_output"); - testOp(browser, "CRC-8 Checksum", "test input", "test_output"); - testOp(browser, "CSS Beautify", "test input", "test_output"); - testOp(browser, "CSS Minify", "test input", "test_output"); - testOp(browser, "CSS selector", "test input", "test_output"); - // testOp(browser, "CSV to JSON", "test input", "test_output"); - testOp(browser, "CTPH", "test input", "test_output"); - // testOp(browser, "Cartesian Product", "test input", "test_output"); - // testOp(browser, "Change IP format", "test input", "test_output"); - testOp(browser, "Chi Square", "test input", "test_output"); - // testOp(browser, "CipherSaber2 Decrypt", "test input", "test_output"); - // testOp(browser, "CipherSaber2 Encrypt", "test input", "test_output"); - // testOp(browser, "Citrix CTX1 Decode", "test input", "test_output"); - // testOp(browser, "Citrix CTX1 Encode", "test input", "test_output"); - // testOp(browser, "Colossus", "test input", "test_output"); - // testOp(browser, "Comment", "test input", "test_output"); - testOp(browser, "Compare CTPH hashes", "test input", "test_output"); - testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); - // /testOp(browser, "Conditional Jump", "test input", "test_output"); - testOp(browser, "Contain Image", "test input", "test_output"); - testOp(browser, "Convert area", "test input", "test_output"); - // /testOp(browser, "Convert co-ordinate format", "test input", "test_output"); - testOp(browser, "Convert data units", "test input", "test_output"); - testOp(browser, "Convert distance", "test input", "test_output"); - // testOp(browser, "Convert Image Format", "test input", "test_output"); - testOp(browser, "Convert mass", "test input", "test_output"); - testOp(browser, "Convert speed", "test input", "test_output"); - // /testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); - testOp(browser, "Count occurrences", "test input", "test_output"); - // testOp(browser, "Cover Image", "test input", "test_output"); - // testOp(browser, "Crop Image", "test input", "test_output"); - // testOp(browser, "DES Decrypt", "test input", "test_output"); - // testOp(browser, "DES Encrypt", "test input", "test_output"); - // testOp(browser, "DNS over HTTPS", "test input", "test_output"); - // testOp(browser, "Dechunk HTTP response", "test input", "test_output"); - // testOp(browser, "Decode NetBIOS Name", "test input", "test_output"); - // testOp(browser, "Decode text", "test input", "test_output"); - // testOp(browser, "Defang IP Addresses", "test input", "test_output"); - // testOp(browser, "Defang URL", "test input", "test_output"); - // testOp(browser, "Derive EVP key", "test input", "test_output"); - // testOp(browser, "Derive PBKDF2 key", "test input", "test_output"); - // testOp(browser, "Detect File Type", "test input", "test_output"); - // testOp(browser, "Diff", "test input", "test_output"); - // testOp(browser, "Disassemble x86", "test input", "test_output"); - // testOp(browser, "Dither Image", "test input", "test_output"); - // testOp(browser, "Divide", "test input", "test_output"); - // testOp(browser, "Drop bytes", "test input", "test_output"); - // testOp(browser, "Encode NetBIOS Name", "test input", "test_output"); - // testOp(browser, "Encode text", "test input", "test_output"); - // testOp(browser, "Enigma", "test input", "test_output"); - // testOp(browser, "Entropy", "test input", "test_output"); - // testOp(browser, "Escape string", "test input", "test_output"); - // testOp(browser, "Escape Unicode Characters", "test input", "test_output"); - // testOp(browser, "Expand alphabet range", "test input", "test_output"); - // testOp(browser, "Extract dates", "test input", "test_output"); - // testOp(browser, "Extract domains", "test input", "test_output"); - // testOp(browser, "Extract EXIF", "test input", "test_output"); - // testOp(browser, "Extract email addresses", "test input", "test_output"); - // testOp(browser, "Extract file paths", "test input", "test_output"); - // testOp(browser, "Extract Files", "test input", "test_output"); - // testOp(browser, "Extract IP addresses", "test input", "test_output"); - // testOp(browser, "Extract LSB", "test input", "test_output"); - // testOp(browser, "Extract MAC addresses", "test input", "test_output"); - // testOp(browser, "Extract RGBA", "test input", "test_output"); - // testOp(browser, "Extract URLs", "test input", "test_output"); - // testOp(browser, "Filter", "test input", "test_output"); - // testOp(browser, "Find / Replace", "test input", "test_output"); - // testOp(browser, "Fletcher-16 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-32 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-64 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-8 Checksum", "test input", "test_output"); - // testOp(browser, "Flip Image", "test input", "test_output"); - // testOp(browser, "Fork", "test input", "test_output"); - // testOp(browser, "Format MAC addresses", "test input", "test_output"); - // testOp(browser, "Frequency distribution", "test input", "test_output"); - // testOp(browser, "From BCD", "test input", "test_output"); - // testOp(browser, "From Base", "test input", "test_output"); - // testOp(browser, "From Base32", "test input", "test_output"); - // testOp(browser, "From Base58", "test input", "test_output"); - // testOp(browser, "From Base62", "test input", "test_output"); - // testOp(browser, "From Base64", "test input", "test_output"); - // testOp(browser, "From Base85", "test input", "test_output"); - // testOp(browser, "From Binary", "test input", "test_output"); - // testOp(browser, "From Braille", "test input", "test_output"); - // testOp(browser, "From Case Insensitive Regex", "test input", "test_output"); - // testOp(browser, "From Charcode", "test input", "test_output"); - // testOp(browser, "From Decimal", "test input", "test_output"); - // testOp(browser, "From HTML Entity", "test input", "test_output"); - // testOp(browser, "From Hex", "test input", "test_output"); - // testOp(browser, "From Hex Content", "test input", "test_output"); - // testOp(browser, "From Hexdump", "test input", "test_output"); - // testOp(browser, "From MessagePack", "test input", "test_output"); - // testOp(browser, "From Morse Code", "test input", "test_output"); - // testOp(browser, "From Octal", "test input", "test_output"); - // testOp(browser, "From Punycode", "test input", "test_output"); - // testOp(browser, "From Quoted Printable", "test input", "test_output"); - // testOp(browser, "From UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "GOST hash", "test input", "test_output"); - // testOp(browser, "Generate all hashes", "test input", "test_output"); - // testOp(browser, "Generate HOTP", "test input", "test_output"); - // testOp(browser, "Generate Image", "test input", "test_output"); - // testOp(browser, "Generate Lorem Ipsum", "test input", "test_output"); - // testOp(browser, "Generate PGP Key Pair", "test input", "test_output"); - // testOp(browser, "Generate QR Code", "test input", "test_output"); - // testOp(browser, "Generate TOTP", "test input", "test_output"); - // testOp(browser, "Generate UUID", "test input", "test_output"); - // testOp(browser, "Generic Code Beautify", "test input", "test_output"); - // testOp(browser, "Group IP addresses", "test input", "test_output"); - // testOp(browser, "Gunzip", "test input", "test_output"); - // testOp(browser, "Gzip", "test input", "test_output"); - // testOp(browser, "HAS-160", "test input", "test_output"); - // testOp(browser, "HMAC", "test input", "test_output"); - // testOp(browser, "HTML To Text", "test input", "test_output"); - // testOp(browser, "HTTP request", "test input", "test_output"); - // testOp(browser, "Hamming Distance", "test input", "test_output"); - // testOp(browser, "Haversine distance", "test input", "test_output"); - // testOp(browser, "Head", "test input", "test_output"); - // testOp(browser, "Heatmap chart", "test input", "test_output"); - // testOp(browser, "Hex Density chart", "test input", "test_output"); - // testOp(browser, "Hex to Object Identifier", "test input", "test_output"); - // testOp(browser, "Hex to PEM", "test input", "test_output"); - // testOp(browser, "Image Brightness / Contrast", "test input", "test_output"); - // testOp(browser, "Image Filter", "test input", "test_output"); - // testOp(browser, "Image Hue/Saturation/Lightness", "test input", "test_output"); - // testOp(browser, "Image Opacity", "test input", "test_output"); - // testOp(browser, "Index of Coincidence", "test input", "test_output"); - // testOp(browser, "Invert Image", "test input", "test_output"); - // testOp(browser, "JPath expression", "test input", "test_output"); - // testOp(browser, "JSON Beautify", "test input", "test_output"); - // testOp(browser, "JSON Minify", "test input", "test_output"); - // testOp(browser, "JSON to CSV", "test input", "test_output"); - // testOp(browser, "JWT Decode", "test input", "test_output"); - // testOp(browser, "JWT Sign", "test input", "test_output"); - // testOp(browser, "JWT Verify", "test input", "test_output"); - // testOp(browser, "JavaScript Beautify", "test input", "test_output"); - // testOp(browser, "JavaScript Minify", "test input", "test_output"); - // testOp(browser, "JavaScript Parser", "test input", "test_output"); - // testOp(browser, "Jump", "test input", "test_output"); - // testOp(browser, "Keccak", "test input", "test_output"); - // testOp(browser, "Label", "test input", "test_output"); - // testOp(browser, "Lorenz", "test input", "test_output"); - // testOp(browser, "Luhn Checksum", "test input", "test_output"); - // testOp(browser, "MD2", "test input", "test_output"); - // testOp(browser, "MD4", "test input", "test_output"); - // testOp(browser, "MD5", "test input", "test_output"); - // testOp(browser, "MD6", "test input", "test_output"); - // testOp(browser, "Magic", "test input", "test_output"); - // testOp(browser, "Mean", "test input", "test_output"); - // testOp(browser, "Median", "test input", "test_output"); - // testOp(browser, "Merge", "test input", "test_output"); - // testOp(browser, "Microsoft Script Decoder", "test input", "test_output"); - // testOp(browser, "Multiple Bombe", "test input", "test_output"); - // testOp(browser, "Multiply", "test input", "test_output"); - // testOp(browser, "NOT", "test input", "test_output"); - // testOp(browser, "Normalise Image", "test input", "test_output"); - // testOp(browser, "Normalise Unicode", "test input", "test_output"); - // testOp(browser, "Numberwang", "test input", "test_output"); - // testOp(browser, "OR", "test input", "test_output"); - // testOp(browser, "Object Identifier to Hex", "test input", "test_output"); - // testOp(browser, "Offset checker", "test input", "test_output"); - // testOp(browser, "Optical Character Recognition", "test input", "test_output"); - // testOp(browser, "PEM to Hex", "test input", "test_output"); - // testOp(browser, "PGP Decrypt", "test input", "test_output"); - // testOp(browser, "PGP Decrypt and Verify", "test input", "test_output"); - // testOp(browser, "PGP Encrypt", "test input", "test_output"); - // testOp(browser, "PGP Encrypt and Sign", "test input", "test_output"); - // testOp(browser, "PGP Verify", "test input", "test_output"); - // testOp(browser, "PHP Deserialize", "test input", "test_output"); - // testOp(browser, "Pad lines", "test input", "test_output"); - // testOp(browser, "Parse ASN.1 hex string", "test input", "test_output"); - // testOp(browser, "Parse colour code", "test input", "test_output"); - // testOp(browser, "Parse DateTime", "test input", "test_output"); - // testOp(browser, "Parse IP range", "test input", "test_output"); - // testOp(browser, "Parse IPv4 header", "test input", "test_output"); - // testOp(browser, "Parse IPv6 address", "test input", "test_output"); - // testOp(browser, "Parse ObjectID timestamp", "test input", "test_output"); - // testOp(browser, "Parse QR Code", "test input", "test_output"); - // testOp(browser, "Parse SSH Host Key", "test input", "test_output"); - // testOp(browser, "Parse TLV", "test input", "test_output"); - // testOp(browser, "Parse UDP", "test input", "test_output"); - // testOp(browser, "Parse UNIX file permissions", "test input", "test_output"); - // testOp(browser, "Parse URI", "test input", "test_output"); - // testOp(browser, "Parse User Agent", "test input", "test_output"); - // testOp(browser, "Parse X.509 certificate", "test input", "test_output"); - // testOp(browser, "Play Media", "test input", "test_output"); - // testOp(browser, "Power Set", "test input", "test_output"); - // testOp(browser, "Protobuf Decode", "test input", "test_output"); - // testOp(browser, "Pseudo-Random Number Generator", "test input", "test_output"); - // testOp(browser, "RC2 Decrypt", "test input", "test_output"); - // testOp(browser, "RC2 Encrypt", "test input", "test_output"); - // testOp(browser, "RC4", "test input", "test_output"); - // testOp(browser, "RC4 Drop", "test input", "test_output"); - // testOp(browser, "RIPEMD", "test input", "test_output"); - // testOp(browser, "ROT13", "test input", "test_output"); - // testOp(browser, "ROT47", "test input", "test_output"); - // testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output"); - // testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output"); - // testOp(browser, "Randomize Colour Palette", "test input", "test_output"); - // testOp(browser, "Raw Deflate", "test input", "test_output"); - // testOp(browser, "Raw Inflate", "test input", "test_output"); - // testOp(browser, "Register", "test input", "test_output"); - // testOp(browser, "Regular expression", "test input", "test_output"); - // testOp(browser, "Remove Diacritics", "test input", "test_output"); - // testOp(browser, "Remove EXIF", "test input", "test_output"); - // testOp(browser, "Remove line numbers", "test input", "test_output"); - // testOp(browser, "Remove null bytes", "test input", "test_output"); - // testOp(browser, "Remove whitespace", "test input", "test_output"); - // testOp(browser, "Render Image", "test input", "test_output"); - // testOp(browser, "Render Markdown", "test input", "test_output"); - // testOp(browser, "Resize Image", "test input", "test_output"); - // testOp(browser, "Return", "test input", "test_output"); - // testOp(browser, "Reverse", "test input", "test_output"); - // testOp(browser, "Rotate Image", "test input", "test_output"); - // testOp(browser, "Rotate left", "test input", "test_output"); - // testOp(browser, "Rotate right", "test input", "test_output"); - // testOp(browser, "SHA0", "test input", "test_output"); - // testOp(browser, "SHA1", "test input", "test_output"); - // testOp(browser, "SHA2", "test input", "test_output"); - // testOp(browser, "SHA3", "test input", "test_output"); - // testOp(browser, "SQL Beautify", "test input", "test_output"); - // testOp(browser, "SQL Minify", "test input", "test_output"); - // testOp(browser, "SSDEEP", "test input", "test_output"); - // testOp(browser, "SUB", "test input", "test_output"); - // testOp(browser, "Scan for Embedded Files", "test input", "test_output"); - // testOp(browser, "Scatter chart", "test input", "test_output"); - // testOp(browser, "Scrypt", "test input", "test_output"); - // testOp(browser, "Series chart", "test input", "test_output"); - // testOp(browser, "Set Difference", "test input", "test_output"); - // testOp(browser, "Set Intersection", "test input", "test_output"); - // testOp(browser, "Set Union", "test input", "test_output"); - // testOp(browser, "Shake", "test input", "test_output"); - // testOp(browser, "Sharpen Image", "test input", "test_output"); - // testOp(browser, "Show Base64 offsets", "test input", "test_output"); - // testOp(browser, "Show on map", "test input", "test_output"); - // testOp(browser, "Sleep", "test input", "test_output"); - // testOp(browser, "Snefru", "test input", "test_output"); - // testOp(browser, "Sort", "test input", "test_output"); - // testOp(browser, "Split", "test input", "test_output"); - // testOp(browser, "Split Colour Channels", "test input", "test_output"); - // testOp(browser, "Standard Deviation", "test input", "test_output"); - // testOp(browser, "Streebog", "test input", "test_output"); - // testOp(browser, "Strings", "test input", "test_output"); - // testOp(browser, "Strip HTML tags", "test input", "test_output"); - // testOp(browser, "Strip HTTP headers", "test input", "test_output"); - // testOp(browser, "Subsection", "test input", "test_output"); - // testOp(browser, "Substitute", "test input", "test_output"); - // testOp(browser, "Subtract", "test input", "test_output"); - // testOp(browser, "Sum", "test input", "test_output"); - // testOp(browser, "Swap endianness", "test input", "test_output"); - // testOp(browser, "Symmetric Difference", "test input", "test_output"); - // testOp(browser, "Syntax highlighter", "test input", "test_output"); - // testOp(browser, "TCP/IP Checksum", "test input", "test_output"); - // testOp(browser, "Tail", "test input", "test_output"); - // testOp(browser, "Take bytes", "test input", "test_output"); - // testOp(browser, "Tar", "test input", "test_output"); - // testOp(browser, "Text Encoding Brute Force", "test input", "test_output"); - // testOp(browser, "To BCD", "test input", "test_output"); - // testOp(browser, "To Base", "test input", "test_output"); - // testOp(browser, "To Base32", "test input", "test_output"); - // testOp(browser, "To Base58", "test input", "test_output"); - // testOp(browser, "To Base62", "test input", "test_output"); - // testOp(browser, "To Base64", "test input", "test_output"); - // testOp(browser, "To Base85", "test input", "test_output"); - // testOp(browser, "To Binary", "test input", "test_output"); - // testOp(browser, "To Braille", "test input", "test_output"); - // testOp(browser, "To Camel case", "test input", "test_output"); - // testOp(browser, "To Case Insensitive Regex", "test input", "test_output"); - // testOp(browser, "To Charcode", "test input", "test_output"); - // testOp(browser, "To Decimal", "test input", "test_output"); - // testOp(browser, "To HTML Entity", "test input", "test_output"); - // testOp(browser, "To Hex", "test input", "test_output"); - // testOp(browser, "To Hex Content", "test input", "test_output"); - // testOp(browser, "To Hexdump", "test input", "test_output"); - // testOp(browser, "To Kebab case", "test input", "test_output"); - // testOp(browser, "To Lower case", "test input", "test_output"); - // testOp(browser, "To MessagePack", "test input", "test_output"); - // testOp(browser, "To Morse Code", "test input", "test_output"); - // testOp(browser, "To Octal", "test input", "test_output"); - // testOp(browser, "To Punycode", "test input", "test_output"); - // testOp(browser, "To Quoted Printable", "test input", "test_output"); - // testOp(browser, "To Snake case", "test input", "test_output"); - // testOp(browser, "To Table", "test input", "test_output"); - // testOp(browser, "To UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "To Upper case", "test input", "test_output"); - // testOp(browser, "Translate DateTime Format", "test input", "test_output"); - // testOp(browser, "Triple DES Decrypt", "test input", "test_output"); - // testOp(browser, "Triple DES Encrypt", "test input", "test_output"); - // testOp(browser, "Typex", "test input", "test_output"); - // testOp(browser, "UNIX Timestamp to Windows Filetime", "test input", "test_output"); - // testOp(browser, "URL Decode", "test input", "test_output"); - // testOp(browser, "URL Encode", "test input", "test_output"); - // testOp(browser, "Unescape string", "test input", "test_output"); - // testOp(browser, "Unescape Unicode Characters", "test input", "test_output"); - // testOp(browser, "Unique", "test input", "test_output"); - // testOp(browser, "Untar", "test input", "test_output"); - // testOp(browser, "Unzip", "test input", "test_output"); - // testOp(browser, "VarInt Decode", "test input", "test_output"); - // testOp(browser, "VarInt Encode", "test input", "test_output"); - // testOp(browser, "View Bit Plane", "test input", "test_output"); - // testOp(browser, "Vigenère Decode", "test input", "test_output"); - // testOp(browser, "Vigenère Encode", "test input", "test_output"); - // testOp(browser, "Whirlpool", "test input", "test_output"); - // testOp(browser, "Windows Filetime to UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "XKCD Random Number", "test input", "test_output"); - // testOp(browser, "XML Beautify", "test input", "test_output"); - // testOp(browser, "XML Minify", "test input", "test_output"); - // testOp(browser, "XOR", "test input", "test_output"); - // testOp(browser, "XOR Brute Force", "test input", "test_output"); - // testOp(browser, "XPath expression", "test input", "test_output"); - // testOp(browser, "YARA Rules", "test input", "test_output"); - // testOp(browser, "Zip", "test input", "test_output"); - // testOp(browser, "Zlib Deflate", "test input", "test_output"); - // testOp(browser, "Zlib Inflate", "test input", "test_output"); + import("../operations/samples/Images.mjs") + .then(Images => { + testOp(browser, ["From Hex", "Add Text To Image", "To Hex"], Images.PNG_HEX, Images.PNG_CHEF_HEX); + testOp(browser, "A1Z26 Cipher Decode", "20 5 19 20 15 21 20 16 21 20", "testoutput"); + testOp(browser, "A1Z26 Cipher Encode", "test input", "20 5 19 20 9 14 16 21 20"); + }); + }, + "Sanity check operations": browser => { + import("../operations/samples/Images.mjs").then(Images => { + testOp(browser, "ADD", "test input", "Ê»ÉÊv¿ÄÆËÊ", [{ "option": "Hex", "string": "56" }]); + testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }]); + testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]); + testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]); + testOp(browser, "Add line numbers", "test input", "1 test input"); + // testOp(browser, ["From Hex", "Add Text To Image", "To Hex"], Images.PNG_HEX, Images.PNG_CHEF_HEX); + // testOp(browser, "Add Text To Image", "test input", "test_output"); + testOp(browser, "Adler-32 Checksum", "test input", "16160411"); + testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]); + testOp(browser, "Affine Cipher Encode", "test input", "njln rbfpn", [2, 1]); + testOp(browser, "Analyse hash", "0123456789abcdef", /CRC-64/); + testOp(browser, "Atbash Cipher", "test input", "gvhg rmkfg"); + // testOp(browser, "Avro to JSON", "test input", "test_output"); + // testOp(browser, "BLAKE2b", "test input", "test_output"); + // testOp(browser, "BLAKE2s", "test input", "test_output"); + // testOp(browser, "BSON deserialise", "test input", "test_output"); + // testOp(browser, "BSON serialise", "test input", "test_output"); + // testOp(browser, "Bacon Cipher Decode", "test input", "test_output"); + // testOp(browser, "Bacon Cipher Encode", "test input", "test_output"); + // testOp(browser, "Bcrypt", "test input", "test_output"); + // testOp(browser, "Bcrypt compare", "test input", "test_output"); + // testOp(browser, "Bcrypt parse", "test input", "test_output"); + // testOp(browser, "Bifid Cipher Decode", "test input", "test_output"); + // testOp(browser, "Bifid Cipher Encode", "test input", "test_output"); + // testOp(browser, "Bit shift left", "test input", "test_output"); + // testOp(browser, "Bit shift right", "test input", "test_output"); + testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]); + testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); + // console.log(Images); + // testOp(browser, "Blur Image", Images.PNG_HEX, "test_output"); + // Imaged Error : Undefined ! Must be a way to Reference Exports + + // testOp(browser, "Bombe", "test input", "test_output"); + testOp(browser, "Bzip2 Compress", "test input", "BZh91AY&SYÏ........@..!N. .!.Â.À.3..ß.rE8P.Ï..."); + testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [true]); + // testOp(browser, "CRC-16 Checksum", "test input", "test_output"); + // testOp(browser, "CRC-32 Checksum", "test input", "test_output"); + // testOp(browser, "CRC-8 Checksum", "test input", "test_output"); + // testOp(browser, "CSS Beautify", "test input", "test_output"); + // testOp(browser, "CSS Minify", "test input", "test_output"); + // testOp(browser, "CSS selector", "test input", "test_output"); + // testOp(browser, "CSV to JSON", "test input", "test_output"); + // testOp(browser, "CTPH", "test input", "test_output"); + // testOp(browser, "Cartesian Product", "test input", "test_output"); + // testOp(browser, "Change IP format", "test input", "test_output"); + // testOp(browser, "Chi Square", "test input", "test_output"); + // testOp(browser, "CipherSaber2 Decrypt", "test input", "test_output"); + // testOp(browser, "CipherSaber2 Encrypt", "test input", "test_output"); + // testOp(browser, "Citrix CTX1 Decode", "test input", "test_output"); + // testOp(browser, "Citrix CTX1 Encode", "test input", "test_output"); + // testOp(browser, "Colossus", "test input", "test_output"); + // testOp(browser, "Comment", "test input", "test_output"); + // testOp(browser, "Compare CTPH hashes", "test input", "test_output"); + // testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); + // /testOp(browser, "Conditional Jump", "test input", "test_output"); + // testOp(browser, "Contain Image", "test input", "test_output"); + // testOp(browser, "Convert area", "test input", "test_output"); + // /testOp(browser, "Convert co-ordinate format", "test input", "test_output"); + // testOp(browser, "Convert data units", "test input", "test_output"); + // testOp(browser, "Convert distance", "test input", "test_output"); + // testOp(browser, "Convert Image Format", "test input", "test_output"); + // testOp(browser, "Convert mass", "test input", "test_output"); + // testOp(browser, "Convert speed", "test input", "test_output"); + // testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); + // testOp(browser, "Count occurrences", "test input", "test_output"); + // testOp(browser, "Cover Image", "test input", "test_output"); + // testOp(browser, "Crop Image", "test input", "test_output"); + // testOp(browser, "DES Decrypt", "test input", "test_output"); + // testOp(browser, "DES Encrypt", "test input", "test_output"); + // testOp(browser, "DNS over HTTPS", "test input", "test_output"); + // testOp(browser, "Dechunk HTTP response", "test input", "test_output"); + // testOp(browser, "Decode NetBIOS Name", "test input", "test_output"); + // testOp(browser, "Decode text", "test input", "test_output"); + // testOp(browser, "Defang IP Addresses", "test input", "test_output"); + // testOp(browser, "Defang URL", "test input", "test_output"); + // testOp(browser, "Derive EVP key", "test input", "test_output"); + // testOp(browser, "Derive PBKDF2 key", "test input", "test_output"); + // testOp(browser, "Detect File Type", "test input", "test_output"); + // testOp(browser, "Diff", "test input", "test_output"); + // testOp(browser, "Disassemble x86", "test input", "test_output"); + // testOp(browser, "Dither Image", "test input", "test_output"); + // testOp(browser, "Divide", "test input", "test_output"); + // testOp(browser, "Drop bytes", "test input", "test_output"); + // testOp(browser, "Encode NetBIOS Name", "test input", "test_output"); + // testOp(browser, "Encode text", "test input", "test_output"); + // testOp(browser, "Enigma", "test input", "test_output"); + // testOp(browser, "Entropy", "test input", "test_output"); + // testOp(browser, "Escape string", "test input", "test_output"); + // testOp(browser, "Escape Unicode Characters", "test input", "test_output"); + // testOp(browser, "Expand alphabet range", "test input", "test_output"); + // testOp(browser, "Extract dates", "test input", "test_output"); + // testOp(browser, "Extract domains", "test input", "test_output"); + // testOp(browser, "Extract EXIF", "test input", "test_output"); + // testOp(browser, "Extract email addresses", "test input", "test_output"); + // testOp(browser, "Extract file paths", "test input", "test_output"); + // testOp(browser, "Extract Files", "test input", "test_output"); + // testOp(browser, "Extract IP addresses", "test input", "test_output"); + // testOp(browser, "Extract LSB", "test input", "test_output"); + // testOp(browser, "Extract MAC addresses", "test input", "test_output"); + // testOp(browser, "Extract RGBA", "test input", "test_output"); + // testOp(browser, "Extract URLs", "test input", "test_output"); + // testOp(browser, "Filter", "test input", "test_output"); + // testOp(browser, "Find / Replace", "test input", "test_output"); + // testOp(browser, "Fletcher-16 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-32 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-64 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-8 Checksum", "test input", "test_output"); + // testOp(browser, "Flip Image", "test input", "test_output"); + // testOp(browser, "Fork", "test input", "test_output"); + // testOp(browser, "Format MAC addresses", "test input", "test_output"); + // testOp(browser, "Frequency distribution", "test input", "test_output"); + // testOp(browser, "From BCD", "test input", "test_output"); + // testOp(browser, "From Base", "test input", "test_output"); + // testOp(browser, "From Base32", "test input", "test_output"); + // testOp(browser, "From Base58", "test input", "test_output"); + // testOp(browser, "From Base62", "test input", "test_output"); + // testOp(browser, "From Base64", "test input", "test_output"); + // testOp(browser, "From Base85", "test input", "test_output"); + // testOp(browser, "From Binary", "test input", "test_output"); + // testOp(browser, "From Braille", "test input", "test_output"); + // testOp(browser, "From Case Insensitive Regex", "test input", "test_output"); + // testOp(browser, "From Charcode", "test input", "test_output"); + // testOp(browser, "From Decimal", "test input", "test_output"); + // testOp(browser, "From HTML Entity", "test input", "test_output"); + // testOp(browser, "From Hex", "test input", "test_output"); + // testOp(browser, "From Hex Content", "test input", "test_output"); + // testOp(browser, "From Hexdump", "test input", "test_output"); + // testOp(browser, "From MessagePack", "test input", "test_output"); + // testOp(browser, "From Morse Code", "test input", "test_output"); + // testOp(browser, "From Octal", "test input", "test_output"); + // testOp(browser, "From Punycode", "test input", "test_output"); + // testOp(browser, "From Quoted Printable", "test input", "test_output"); + // testOp(browser, "From UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "GOST hash", "test input", "test_output"); + // testOp(browser, "Generate all hashes", "test input", "test_output"); + // testOp(browser, "Generate HOTP", "test input", "test_output"); + // testOp(browser, "Generate Image", "test input", "test_output"); + // testOp(browser, "Generate Lorem Ipsum", "test input", "test_output"); + // testOp(browser, "Generate PGP Key Pair", "test input", "test_output"); + // testOp(browser, "Generate QR Code", "test input", "test_output"); + // testOp(browser, "Generate TOTP", "test input", "test_output"); + // testOp(browser, "Generate UUID", "test input", "test_output"); + // testOp(browser, "Generic Code Beautify", "test input", "test_output"); + // testOp(browser, "Group IP addresses", "test input", "test_output"); + // testOp(browser, "Gunzip", "test input", "test_output"); + // testOp(browser, "Gzip", "test input", "test_output"); + // testOp(browser, "HAS-160", "test input", "test_output"); + // testOp(browser, "HMAC", "test input", "test_output"); + // testOp(browser, "HTML To Text", "test input", "test_output"); + // testOp(browser, "HTTP request", "test input", "test_output"); + // testOp(browser, "Hamming Distance", "test input", "test_output"); + // testOp(browser, "Haversine distance", "test input", "test_output"); + // testOp(browser, "Head", "test input", "test_output"); + // testOp(browser, "Heatmap chart", "test input", "test_output"); + // testOp(browser, "Hex Density chart", "test input", "test_output"); + // testOp(browser, "Hex to Object Identifier", "test input", "test_output"); + // testOp(browser, "Hex to PEM", "test input", "test_output"); + // testOp(browser, "Image Brightness / Contrast", "test input", "test_output"); + // testOp(browser, "Image Filter", "test input", "test_output"); + // testOp(browser, "Image Hue/Saturation/Lightness", "test input", "test_output"); + // testOp(browser, "Image Opacity", "test input", "test_output"); + // testOp(browser, "Index of Coincidence", "test input", "test_output"); + // testOp(browser, "Invert Image", "test input", "test_output"); + // testOp(browser, "JPath expression", "test input", "test_output"); + // testOp(browser, "JSON Beautify", "test input", "test_output"); + // testOp(browser, "JSON Minify", "test input", "test_output"); + // testOp(browser, "JSON to CSV", "test input", "test_output"); + // testOp(browser, "JWT Decode", "test input", "test_output"); + // testOp(browser, "JWT Sign", "test input", "test_output"); + // testOp(browser, "JWT Verify", "test input", "test_output"); + // testOp(browser, "JavaScript Beautify", "test input", "test_output"); + // testOp(browser, "JavaScript Minify", "test input", "test_output"); + // testOp(browser, "JavaScript Parser", "test input", "test_output"); + // testOp(browser, "Jump", "test input", "test_output"); + // testOp(browser, "Keccak", "test input", "test_output"); + // testOp(browser, "Label", "test input", "test_output"); + // testOp(browser, "Lorenz", "test input", "test_output"); + // testOp(browser, "Luhn Checksum", "test input", "test_output"); + // testOp(browser, "MD2", "test input", "test_output"); + // testOp(browser, "MD4", "test input", "test_output"); + // testOp(browser, "MD5", "test input", "test_output"); + // testOp(browser, "MD6", "test input", "test_output"); + // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "td", /Result snippet/); + // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:nth-of-type(1) td:nth-of-type(2)", "Result snippet"); + // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:eq(1) td:eq(1)", "test_output"); + // testOp(browser, "Mean", "test input", "test_output"); + // testOp(browser, "Median", "test input", "test_output");` + // testOp(browser, "Merge", "test input", "test_output");` + // testOp(browser, "Microsoft Script Decoder", "test input", "test_output"); + // testOp(browser, "Multiple Bombe", "test input", "test_output"); + // testOp(browser, "Multiply", "test input", "test_output"); + // testOp(browser, "NOT", "test input", "test_output"); + // testOp(browser, "Normalise Image", "test input", "test_output"); + // testOp(browser, "Normalise Unicode", "test input", "test_output"); + // testOp(browser, "Numberwang", "test input", "test_output"); + // testOp(browser, "OR", "test input", "test_output"); + // testOp(browser, "Object Identifier to Hex", "test input", "test_output"); + // testOp(browser, "Offset checker", "test input", "test_output"); + // testOp(browser, "Optical Character Recognition", "test input", "test_output"); + // testOp(browser, "PEM to Hex", "test input", "test_output"); + // testOp(browser, "PGP Decrypt", "test input", "test_output"); + // testOp(browser, "PGP Decrypt and Verify", "test input", "test_output"); + // testOp(browser, "PGP Encrypt", "test input", "test_output"); + // testOp(browser, "PGP Encrypt and Sign", "test input", "test_output"); + // testOp(browser, "PGP Verify", "test input", "test_output"); + // testOp(browser, "PHP Deserialize", "test input", "test_output"); + // testOp(browser, "Pad lines", "test input", "test_output"); + // testOp(browser, "Parse ASN.1 hex string", "test input", "test_output"); + // testOp(browser, "Parse colour code", "test input", "test_output"); + // testOp(browser, "Parse DateTime", "test input", "test_output"); + // testOp(browser, "Parse IP range", "test input", "test_output"); + // testOp(browser, "Parse IPv4 header", "test input", "test_output"); + // testOp(browser, "Parse IPv6 address", "test input", "test_output"); + // testOp(browser, "Parse ObjectID timestamp", "test input", "test_output"); + // testOp(browser, "Parse QR Code", "test input", "test_output"); + // testOp(browser, "Parse SSH Host Key", "test input", "test_output"); + // testOp(browser, "Parse TLV", "test input", "test_output"); + // testOp(browser, "Parse UDP", "test input", "test_output"); + // testOp(browser, "Parse UNIX file permissions", "test input", "test_output"); + // testOp(browser, "Parse URI", "test input", "test_output"); + // testOp(browser, "Parse User Agent", "test input", "test_output"); + // testOp(browser, "Parse X.509 certificate", "test input", "test_output"); + // testOp(browser, "Play Media", "test input", "test_output"); + // testOp(browser, "Power Set", "test input", "test_output"); + // testOp(browser, "Protobuf Decode", "test input", "test_output"); + // testOp(browser, "Pseudo-Random Number Generator", "test input", "test_output"); + // testOp(browser, "RC2 Decrypt", "test input", "test_output"); + // testOp(browser, "RC2 Encrypt", "test input", "test_output"); + // testOp(browser, "RC4", "test input", "test_output"); + // testOp(browser, "RC4 Drop", "test input", "test_output"); + // testOp(browser, "RIPEMD", "test input", "test_output"); + // testOp(browser, "ROT13", "test input", "test_output"); + // testOp(browser, "ROT47", "test input", "test_output"); + // testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output"); + // testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output"); + // testOp(browser, "Randomize Colour Palette", "test input", "test_output"); + // testOp(browser, "Raw Deflate", "test input", "test_output"); + // testOp(browser, "Raw Inflate", "test input", "test_output"); + // testOp(browser, "Register", "test input", "test_output"); + // testOp(browser, "Regular expression", "test input", "test_output"); + // testOp(browser, "Remove Diacritics", "test input", "test_output"); + // testOp(browser, "Remove EXIF", "test input", "test_output"); + // testOp(browser, "Remove line numbers", "test input", "test_output"); + // testOp(browser, "Remove null bytes", "test input", "test_output"); + // testOp(browser, "Remove whitespace", "test input", "test_output"); + // testOp(browser, "Render Image", "test input", "test_output"); + // testOp(browser, "Render Markdown", "test input", "test_output"); + // testOp(browser, "Resize Image", "test input", "test_output"); + // testOp(browser, "Return", "test input", "test_output"); + // testOp(browser, "Reverse", "test input", "test_output"); + // testOp(browser, "Rotate Image", "test input", "test_output"); + // testOp(browser, "Rotate left", "test input", "test_output"); + // testOp(browser, "Rotate right", "test input", "test_output"); + // testOp(browser, "SHA0", "test input", "test_output"); + // testOp(browser, "SHA1", "test input", "test_output"); + // testOp(browser, "SHA2", "test input", "test_output"); + // testOp(browser, "SHA3", "test input", "test_output"); + // testOp(browser, "SQL Beautify", "test input", "test_output"); + // testOp(browser, "SQL Minify", "test input", "test_output"); + // testOp(browser, "SSDEEP", "test input", "test_output"); + // testOp(browser, "SUB", "test input", "test_output"); + // testOp(browser, "Scan for Embedded Files", "test input", "test_output"); + // testOp(browser, "Scatter chart", "test input", "test_output"); + // testOp(browser, "Scrypt", "test input", "test_output"); + // testOp(browser, "Series chart", "test input", "test_output"); + // testOp(browser, "Set Difference", "test input", "test_output"); + // testOp(browser, "Set Intersection", "test input", "test_output"); + // testOp(browser, "Set Union", "test input", "test_output"); + // testOp(browser, "Shake", "test input", "test_output"); + // testOp(browser, "Sharpen Image", "test input", "test_output"); + // testOp(browser, "Show Base64 offsets", "test input", "test_output"); + // testOp(browser, "Show on map", "test input", "test_output"); + // testOp(browser, "Sleep", "test input", "test_output"); + // testOp(browser, "Snefru", "test input", "test_output"); + // testOp(browser, "Sort", "test input", "test_output"); + // testOp(browser, "Split", "test input", "test_output"); + // testOp(browser, "Split Colour Channels", "test input", "test_output"); + // testOp(browser, "Standard Deviation", "test input", "test_output"); + // testOp(browser, "Streebog", "test input", "test_output"); + // testOp(browser, "Strings", "test input", "test_output"); + // testOp(browser, "Strip HTML tags", "test input", "test_output"); + // testOp(browser, "Strip HTTP headers", "test input", "test_output"); + // testOp(browser, "Subsection", "test input", "test_output"); + // testOp(browser, "Substitute", "test input", "test_output"); + // testOp(browser, "Subtract", "test input", "test_output"); + // testOp(browser, "Sum", "test input", "test_output"); + // testOp(browser, "Swap endianness", "test input", "test_output"); + // testOp(browser, "Symmetric Difference", "test input", "test_output"); + // testOp(browser, "Syntax highlighter", "test input", "test_output"); + // testOp(browser, "TCP/IP Checksum", "test input", "test_output"); + // testOp(browser, "Tail", "test input", "test_output"); + // testOp(browser, "Take bytes", "test input", "test_output"); + // testOp(browser, "Tar", "test input", "test_output"); + // testOp(browser, "Text Encoding Brute Force", "test input", "test_output"); + // testOp(browser, "To BCD", "test input", "test_output"); + // testOp(browser, "To Base", "test input", "test_output"); + // testOp(browser, "To Base32", "test input", "test_output"); + // testOp(browser, "To Base58", "test input", "test_output"); + // testOp(browser, "To Base62", "test input", "test_output"); + // testOp(browser, "To Base64", "test input", "test_output"); + // testOp(browser, "To Base85", "test input", "test_output"); + // testOp(browser, "To Binary", "test input", "test_output"); + // testOp(browser, "To Braille", "test input", "test_output"); + // testOp(browser, "To Camel case", "test input", "test_output"); + // testOp(browser, "To Case Insensitive Regex", "test input", "test_output"); + // testOp(browser, "To Charcode", "test input", "test_output"); + // testOp(browser, "To Decimal", "test input", "test_output"); + // testOp(browser, "To HTML Entity", "test input", "test_output"); + // testOp(browser, "To Hex", "test input", "test_output"); + // testOp(browser, "To Hex Content", "test input", "test_output"); + // testOp(browser, "To Hexdump", "test input", "test_output"); + // testOp(browser, "To Kebab case", "test input", "test_output"); + // testOp(browser, "To Lower case", "test input", "test_output"); + // testOp(browser, "To MessagePack", "test input", "test_output"); + // testOp(browser, "To Morse Code", "test input", "test_output"); + // testOp(browser, "To Octal", "test input", "test_output"); + // testOp(browser, "To Punycode", "test input", "test_output"); + // testOp(browser, "To Quoted Printable", "test input", "test_output"); + // testOp(browser, "To Snake case", "test input", "test_output"); + // testOp(browser, "To Table", "test input", "test_output"); + // testOp(browser, "To UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "To Upper case", "test input", "test_output"); + // testOp(browser, "Translate DateTime Format", "test input", "test_output"); + // testOp(browser, "Triple DES Decrypt", "test input", "test_output"); + // testOp(browser, "Triple DES Encrypt", "test input", "test_output"); + // testOp(browser, "Typex", "test input", "test_output"); + // testOp(browser, "UNIX Timestamp to Windows Filetime", "test input", "test_output"); + // testOp(browser, "URL Decode", "test input", "test_output"); + // testOp(browser, "URL Encode", "test input", "test_output"); + // testOp(browser, "Unescape string", "test input", "test_output"); + // testOp(browser, "Unescape Unicode Characters", "test input", "test_output"); + // testOp(browser, "Unique", "test input", "test_output"); + // testOp(browser, "Untar", "test input", "test_output"); + // testOp(browser, "Unzip", "test input", "test_output"); + // testOp(browser, "VarInt Decode", "test input", "test_output"); + // testOp(browser, "VarInt Encode", "test input", "test_output"); + // testOp(browser, "View Bit Plane", "test input", "test_output"); + // testOp(browser, "Vigenère Decode", "test input", "test_output"); + // testOp(browser, "Vigenère Encode", "test input", "test_output"); + // testOp(browser, "Whirlpool", "test input", "test_output"); + // testOp(browser, "Windows Filetime to UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "XKCD Random Number", "test input", "test_output"); + // testOp(browser, "XML Beautify", "test input", "test_output"); + // testOp(browser, "XML Minify", "test input", "test_output"); + // testOp(browser, "XOR", "test input", "test_output"); + // testOp(browser, "XOR Brute Force", "test input", "test_output"); + // testOp(browser, "XPath expression", "test input", "test_output"); + // testOp(browser, "YARA Rules", "test input", "test_output"); + // testOp(browser, "Zip", "test input", "test_output"); + // testOp(browser, "Zlib Deflate", "test input", "test_output"); + // testOp(browser, "Zlib Inflate", "test input", "test_output"); + }); }, @@ -376,22 +387,47 @@ module.exports = { }; /** - * Clears the current recipe and tests a new operation. + * Clears the current recipe and bakes a new operation. * * @param {string} opName * @param {Browser} browser */ -function testOp(browser, opName, input, output, args=[]) { +function bakeOp(browser, opName, input, args=[]) { - const recipeConfig = JSON.stringify([{ - "op": opName, - "args": args - }]); + let recipeConfig; + /* + * Create recipeConfig as single operation + * or wrapped with a pre-op and + * possibly a post-op too + */ + if (typeof(opName) === "string") { + recipeConfig = JSON.stringify([{ + "op": opName, + "args": args + }]); + } else if (opName.length === 2) { + recipeConfig = JSON.stringify([{ + "op": opName[0], + "args": [] + }, { + "op": opName[1], + "args": args + }]); + } else { + recipeConfig = JSON.stringify([{ + "op": opName[0], + "args": [] + }, { + "op": opName[1], + "args": args + }, { + "op": opName[2], + "args": [] + + }]); + } browser - .perform(function() { - console.log(opName); - }) .useCss() .click("#clr-recipe") .click("#clr-io") @@ -400,6 +436,14 @@ function testOp(browser, opName, input, output, args=[]) { browser .urlHash("recipe=" + recipeConfig) + .url(function(result) { + currentUrl = result; + }) + .perform(function() { + console.log(currentUrl); + console.log(opName); + console.log(recipeConfig); + }) .setValue("#input-text", input) .waitForElementPresent("#rec-list li.operation") .expect.element("#input-text").to.have.value.that.equals(input); @@ -412,9 +456,46 @@ function testOp(browser, opName, input, output, args=[]) { .waitForElementPresent("#stale-indicator.hidden", 5000) .waitForElementNotVisible("#output-loader", 5000); + let currentUrl=""; + browser + .url(function(result) { + currentUrl = result; + }) + .perform(function() { + console.log(currentUrl.value); + }); +} + +/** + * Clears the current recipe and tests a new operation. + * + * @param {string} opName + * @param {Browser} browser + */ +function testOp(browser, opName, input, output, args=[]) { + + bakeOp(browser, opName, input, args); + if (typeof output === "string") { browser.expect.element("#output-text").to.have.value.that.equals(output); } else if (output instanceof RegExp) { browser.expect.element("#output-text").to.have.value.that.matches(output); } } + +/** + * Clears the current recipe and tests a new operation. + * + * @param {string} opName + * @param {Browser} browser + */ +function testOpHtml(browser, opName, input, element, output, args=[]) { + + bakeOp(browser, opName, input, args); + browser.waitForElementPresent("#output-html", 5000); + if (typeof output === "string") { + browser.expect.element("#output-html " + element).to.have.value.that.equals(output); + } else if (output instanceof RegExp) { + browser.expect.element("#output-html " + element).to.have.value.that.matches(output); + } +} diff --git a/tests/operations/samples/Images.mjs b/tests/operations/samples/Images.mjs index 663fa201..396e9f7d 100644 --- a/tests/operations/samples/Images.mjs +++ b/tests/operations/samples/Images.mjs @@ -18,6 +18,12 @@ export const GIF_ANIMATED_HEX = "4749463839610f000f00b30b00424242ffe700ffef00ffc */ export const PNG_HEX = "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af400000006624b474400ff00ff00ffa0bda793000000097048597300000dd700000dd70142289b78000005184944415458c3c5575d6c145514feeeccecccacdbddb6e096a5dbcdb6d06d80d06090466d6953454ab52ad0a65589840ac1d02a313c989af062820fa66210130d9a68b0363c34610135690b188b7183c13f44506c8115ba535ab6ddd2617f667f66ae0fb41596ddee2eadf13c4de69e7bcf77cff9cecf25b83f613b3b3b975b2c96f25028c47a3c9e1f5a5a5a7e05a0016000d0c9ef9442d23448a60edeb973a769c78e1d077272721a65594620106000505996bf1a1f1f3f67369bebc2e1f0ef6bd7aedd0a409d2d00e2743a1f2929296915046199a66901007aa3d1580600131313da24000000a594124288aaaab72a2b2bed1d1d1d8f8ba2386fc3860d9f25f3c84c0088cbe56a2d2c2cdc4708d12552880770a7288a3228088215003c1ecfd68d1b377e9e488f4b66dde974aeb2dbed498da71251146d538ed1b4e4746092dddee170b4300ca3c32c251c0edfd8bc79f3d164de4e0680110461794a02119292c482202c387efcf86f3d3d3d7b13814816024a2955e62a8b4451b4abaafad8e485d5743ca005028153699c4dd30c83140a857e4c9409c900a0bbbbfbc368343a34a3754a693a1c58b76eddf2dadada5d89002705b07bf7eee13367ce3cab284aff6c482808425e6767e70bc9ea0033d3e6c6c6c65fd6ac5953a1695a3453c3a150c84d295529a59aa669914cd3705adc6eb7926eaca74455d5605555d5c3030303f59224bd525f5f7f30992e87ff40344d5328a5caa64d9bbe4ca5cbe07f1666ae522dae40a5dd8ed30941c8e5727d63341a9f8a5f181a1ac2f0f07022029e02109d2b00bae2e26207cbb2f72cf03c8f9c9c9c441c580c804dc70b330258b6c020beb87ac9abecb59f8b087377b4f4f30a68b6de482549a29224ddb5168bc51cd5d5d54ff6f5f575cfa69633edeb971c78e2d195db055e77cfb6a2eaadb816e5b59ffafb19a7d3095555e3ab64341a8d96f6f6f6fe755f247c69d542abd9c0bd3c70f90a628c30fd5f56542c5c550fc3837600406e6e2eca9e2e433837fcefc0c8b2e079fe7b9fcfe7aba9a9296613c52f55084acc864a027013b28c828a2d30e805bcbe670fac4b5740f5a9285b18c6a0db4da8c180fdc6fdb035d850c555a174a4148410b85cae7293c97442a7d395363434347775757d91b6075a2a6c45d66ce18369258685de644659d96af45ff80345f9f908c932821313c4eff7639b6d1b06838358242c82d96c86288abe582ce6e6797e052184701c9797910796e61976b10c991fff7f7b5313b6373541d5340426d36f747414e5c67294679503a1e90634e6f57adbac56ebb14020f0e9a14387decf84038c8e232b53b45888dc6dec63636389d290c9caca5a3d09a6a2a6a6a628130054d33092a2c52272bbe4515996113f16288ab2c86432bd01001cc72db5582caf651202eaf5473e7e80d7af270409d9cb320c0c66331ca5a5602c1624180d492412392bcbf2db46a3f1394992f665c481b77a2f9f78e719476b5e16ff2e00d31dae8524cb30e8f560390ee72e5e243d7d7d34168bc16030a87575752ccbb20400a2d1e8b7478e1c390ce0f0fd5442fae6d7039f343d643956345f5fcbf1fafd00b219868145afc78d4b97101a1b833a32426d361bcdcfcf87cd6663a7a6649ee70725497a6faede86e4c2c993cf171716eee5753aeb9d0b7f5ebfae5df67a99b86164e8e6cd9badcdcdcdc7d27ae5a6a3f45147c7794dd30e2e59bcf896c0f3851ccbe602c0a8df4fc783413269d8130c06f79d3e7d7a4b5b5bdbd9b45b77c60304c3f0df75752db31714acf8dbe7cbbee2f5fafd7efff9f6f6f6b357af5e8d647ade3fa1780bad734c65970000000049454e44ae426082"; +/** + * The CyberChef logo with 'chef' + * 32x32 + */ +export const PNG_CHEF_HEX = "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af4000006e4494441547801a5c17d6c947701c0f1efeff73cf7debbbed0d2a3c7515e5ae81bd1c2601bd0256685e29808a84c9bc00cfec14b8448b205636234997f2ca8c1f9075163c8d61582246b9913df161184a6c46a24a3a1b4bb513aeee8fb95bb722fcf5def797c6a21e5e55abaf9f9083e1fa5b9b9b9c6ebf5ae4b24124a3018bcb27ffffeff003a200103d09903c1dc084002c6c183073dfbf6edfb555e5ede37a2d128b1584c0246341afd606c6ceca3a2a2a22d9aa65ddbb871e31e20c353a8cc4eb4b4b43cbb7cf9f203369bad4ad7f518e070bbdd6b98a23345783c9ead6eb7fb2bc264b3d9caac56ebf79a9a9abe64b7db0bb66ddb7602d0c9423033d1d6d67660f1e2c5c7841016b28844227a2c169364914c266fdb6c361fa66030b867fbf6edef9085ca0c5a5a5a9e292d2d3d2684b0f039d8ed763f530c5dd79989243b515e5ebe5f4a69e1ffa469dad0ae5dbbce02822c14b2530e1f3efc03abd5ea6316a9548a542a259885aaaa39df32eddcb9d3dfdcdcfc218f51c9ce3025793ac11cd8edf6d24c26f33c20810c0f9164a7c762b18b3c9dc11c689a164a24121d80ce631466b068d1a2ae9a9a9a464551dcdc97c964300c0329259392c9a4914ea705b3d0346da8a1a1a1eac48913bf070ca6496081c2a316017540d5f9f3e78b2a2b2bff585a5aba5a55d579985a5b5b0904025454543049d334239d4e0b66a1aaaaabbebebeeff4e9d31d4c73027b81f592699b815701158803b97bf7ee5d5557577748d7f534264551501485b9482412bd8661640cc3d04d291eb50e70026fa94c59013c0b9c006e33ad2e140a6d8d442296fcfc7ce62a93c9c45f78e185d5274f9eac733a9d453b76ec789b47f9818f8188ca94e7804ee0368ffa27f0b54020c09a356b7820994cd2dddd4d2412910e87039fcfc7c3344dd30dc358d1d8d83804dc649a0aac053c80049e9380022c003ee5491a70b4baba9a07464646686e6ea6b7b7974020c0b973e7e8eeeee681f1f171ce9e3d9b036c0096029b80ef00164001ca003b900f2c530107e00286c92e62b7db53801553341aa5b1b191c2c242229188ded2d2223b3b3b59b16205932e5fbe8ccbe5c2741c88032e601fb01ab80234017b8061e00395290230c82ed1d6d6f637b7dbfde5bebe3ea49404834182c12077eedc21180c12080470b95c4c4c4c70e1c2052a2b2b3b8134a00049e026b014b8c23481490574200338c9ce52565656ae280a797979a8aa4a49490993ac562be17098bb77ef525151c1c0c000f3e7cfa7bfbfbf0678134833450706c94205e24014980f74f190aa62977d7da5ffd4e0bfff5ae62b2e428cf4225405d1f72f1c050b8d5c87db4824128c8e8ed2d3d36384c361313232426d6d2d757575572e5dbaf427a6e96421997203a80604d3e4d76b4b7e674875bbd1db810c5c420cde400c7421039729713a854b5184896030487b7bbbe8eaea22180cd2d1d1416e6eeec98686061f700f880371b2904c69030a8097012ba6576abd55b7c7e25b0d2d8eb7681e0f24523a0b9ed981abb094496eb71bdf721f5abe8694128fc743381c46d7f54fc2a6fafafa9552ca5dc02ab2509892046e016b804d409dd7637ba3c065295ce97550d7f8238a2bd6f1c63b2d8cbbfd2c29aba1b8a0806bd7af33343e2edeed7f17e72b4e6ad7d6b279f9662c160b3d3d3d85baaebfae69dafe850b17e68442a15f02134c5905c4816e856911a003b8feedb5beb117cb0b5e2b2b744a4c351bb6e329282692d0f83418e49b2fbd8448a709f4f60ae976b3e0f905b4c5dad8e6d986dfeea7a4a4243c3a3a7ab7b8b8d85d5c5c4c6e6eeef16bd7ae5d62da2de026905279d2f02a9ffb87393645e5318776efe6d0eedd64749dd8c00093a2d128f5f3eaa9cfa98704ff63b3d9462391c86b3e9feffd582cf6db53a74efd82478d719fe449d2a28a55cc42d334ecaacaa4d1d1511ea7ebbaccc9c9d980c966b3addfb469d31266207992a1eb0c320b9bcd460a931046341ac5300c1e964c26977a3c9ed731a9aa5ae9f57abfcb0c549e640cdf4bfdda69757c550814b250a4c4555444f9ca9548af1721048f11a954ea6a341afd89dbedde1a0a858e3103952c7efc974f3e7cf3e5f203f373ac3f053cdca7eb3aa1681497c381a2aa7c74e386f8f3850bc6c4c4042e972bb365cb16c52430a5d3e9bfb7b6b6be07bcc72c54b233beff878f7fb3f38bdef797cc736c56ad8eb7805c29255e8783a14080c4e82899c141c3eff71b252525f8fd7e45983059add6dba150e8e7cc81ca2cce5c1d18049a760f0d6b654ed7cfac168bcf62b3e1abae6652babfdfc81b1e963c2493c9dc89c7e3072f5ebc18620e14e6e0785353a7aeeb6f572c5b366eb35a17ab8a928f69e4de3d632c1e179832994c301e8f1f6b6f6f7ff5c89123579923c16724a5b4fee3cc99aad2850bbf702b1ccebd393c7ccfd479f4e8d1ab7d7d7d293ea3ff02d269af2f0fa7289f0000000049454e44ae426082"; + /** * Sunglasses smiley * 32x32 From 7b497181fdceea62dccfab846c41247a14abc2ff Mon Sep 17 00:00:00 2001 From: John L Date: Mon, 4 Apr 2022 17:40:58 +0100 Subject: [PATCH 030/111] refactor samples, and more tests --- tests/browser/ops.js | 712 ++++++++++----------- tests/operations/tests/Image.mjs | 2 +- tests/operations/tests/Magic.mjs | 2 +- tests/operations/tests/PGP.mjs | 2 +- tests/operations/tests/RSA.mjs | 2 +- tests/{operations => }/samples/Ciphers.mjs | 0 tests/{operations => }/samples/Images.mjs | 8 +- 7 files changed, 361 insertions(+), 367 deletions(-) rename tests/{operations => }/samples/Ciphers.mjs (100%) rename tests/{operations => }/samples/Images.mjs (90%) diff --git a/tests/browser/ops.js b/tests/browser/ops.js index 49e7c63a..90747aef 100644 --- a/tests/browser/ops.js +++ b/tests/browser/ops.js @@ -16,368 +16,356 @@ module.exports = { .click("#auto-bake-label"); }, - "Sanity check operations": browser => { - import("../operations/samples/Images.mjs") - .then(Images => { - testOp(browser, ["From Hex", "Add Text To Image", "To Hex"], Images.PNG_HEX, Images.PNG_CHEF_HEX); - testOp(browser, "A1Z26 Cipher Decode", "20 5 19 20 15 21 20 16 21 20", "testoutput"); - testOp(browser, "A1Z26 Cipher Encode", "test input", "20 5 19 20 9 14 16 21 20"); - }); - }, - "Sanity check operations": browser => { - import("../operations/samples/Images.mjs").then(Images => { - testOp(browser, "ADD", "test input", "Ê»ÉÊv¿ÄÆËÊ", [{ "option": "Hex", "string": "56" }]); - testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }]); - testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]); - testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]); - testOp(browser, "Add line numbers", "test input", "1 test input"); - // testOp(browser, ["From Hex", "Add Text To Image", "To Hex"], Images.PNG_HEX, Images.PNG_CHEF_HEX); - // testOp(browser, "Add Text To Image", "test input", "test_output"); - testOp(browser, "Adler-32 Checksum", "test input", "16160411"); - testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]); - testOp(browser, "Affine Cipher Encode", "test input", "njln rbfpn", [2, 1]); - testOp(browser, "Analyse hash", "0123456789abcdef", /CRC-64/); - testOp(browser, "Atbash Cipher", "test input", "gvhg rmkfg"); - // testOp(browser, "Avro to JSON", "test input", "test_output"); - // testOp(browser, "BLAKE2b", "test input", "test_output"); - // testOp(browser, "BLAKE2s", "test input", "test_output"); - // testOp(browser, "BSON deserialise", "test input", "test_output"); - // testOp(browser, "BSON serialise", "test input", "test_output"); - // testOp(browser, "Bacon Cipher Decode", "test input", "test_output"); - // testOp(browser, "Bacon Cipher Encode", "test input", "test_output"); - // testOp(browser, "Bcrypt", "test input", "test_output"); - // testOp(browser, "Bcrypt compare", "test input", "test_output"); - // testOp(browser, "Bcrypt parse", "test input", "test_output"); - // testOp(browser, "Bifid Cipher Decode", "test input", "test_output"); - // testOp(browser, "Bifid Cipher Encode", "test input", "test_output"); - // testOp(browser, "Bit shift left", "test input", "test_output"); - // testOp(browser, "Bit shift right", "test input", "test_output"); - testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]); - testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); - // console.log(Images); - // testOp(browser, "Blur Image", Images.PNG_HEX, "test_output"); - // Imaged Error : Undefined ! Must be a way to Reference Exports - - // testOp(browser, "Bombe", "test input", "test_output"); - testOp(browser, "Bzip2 Compress", "test input", "BZh91AY&SYÏ........@..!N. .!.Â.À.3..ß.rE8P.Ï..."); - testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [true]); - // testOp(browser, "CRC-16 Checksum", "test input", "test_output"); - // testOp(browser, "CRC-32 Checksum", "test input", "test_output"); - // testOp(browser, "CRC-8 Checksum", "test input", "test_output"); - // testOp(browser, "CSS Beautify", "test input", "test_output"); - // testOp(browser, "CSS Minify", "test input", "test_output"); - // testOp(browser, "CSS selector", "test input", "test_output"); - // testOp(browser, "CSV to JSON", "test input", "test_output"); - // testOp(browser, "CTPH", "test input", "test_output"); - // testOp(browser, "Cartesian Product", "test input", "test_output"); - // testOp(browser, "Change IP format", "test input", "test_output"); - // testOp(browser, "Chi Square", "test input", "test_output"); - // testOp(browser, "CipherSaber2 Decrypt", "test input", "test_output"); - // testOp(browser, "CipherSaber2 Encrypt", "test input", "test_output"); - // testOp(browser, "Citrix CTX1 Decode", "test input", "test_output"); - // testOp(browser, "Citrix CTX1 Encode", "test input", "test_output"); - // testOp(browser, "Colossus", "test input", "test_output"); - // testOp(browser, "Comment", "test input", "test_output"); - // testOp(browser, "Compare CTPH hashes", "test input", "test_output"); - // testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); - // /testOp(browser, "Conditional Jump", "test input", "test_output"); - // testOp(browser, "Contain Image", "test input", "test_output"); - // testOp(browser, "Convert area", "test input", "test_output"); - // /testOp(browser, "Convert co-ordinate format", "test input", "test_output"); - // testOp(browser, "Convert data units", "test input", "test_output"); - // testOp(browser, "Convert distance", "test input", "test_output"); - // testOp(browser, "Convert Image Format", "test input", "test_output"); - // testOp(browser, "Convert mass", "test input", "test_output"); - // testOp(browser, "Convert speed", "test input", "test_output"); - // testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); - // testOp(browser, "Count occurrences", "test input", "test_output"); - // testOp(browser, "Cover Image", "test input", "test_output"); - // testOp(browser, "Crop Image", "test input", "test_output"); - // testOp(browser, "DES Decrypt", "test input", "test_output"); - // testOp(browser, "DES Encrypt", "test input", "test_output"); - // testOp(browser, "DNS over HTTPS", "test input", "test_output"); - // testOp(browser, "Dechunk HTTP response", "test input", "test_output"); - // testOp(browser, "Decode NetBIOS Name", "test input", "test_output"); - // testOp(browser, "Decode text", "test input", "test_output"); - // testOp(browser, "Defang IP Addresses", "test input", "test_output"); - // testOp(browser, "Defang URL", "test input", "test_output"); - // testOp(browser, "Derive EVP key", "test input", "test_output"); - // testOp(browser, "Derive PBKDF2 key", "test input", "test_output"); - // testOp(browser, "Detect File Type", "test input", "test_output"); - // testOp(browser, "Diff", "test input", "test_output"); - // testOp(browser, "Disassemble x86", "test input", "test_output"); - // testOp(browser, "Dither Image", "test input", "test_output"); - // testOp(browser, "Divide", "test input", "test_output"); - // testOp(browser, "Drop bytes", "test input", "test_output"); - // testOp(browser, "Encode NetBIOS Name", "test input", "test_output"); - // testOp(browser, "Encode text", "test input", "test_output"); - // testOp(browser, "Enigma", "test input", "test_output"); - // testOp(browser, "Entropy", "test input", "test_output"); - // testOp(browser, "Escape string", "test input", "test_output"); - // testOp(browser, "Escape Unicode Characters", "test input", "test_output"); - // testOp(browser, "Expand alphabet range", "test input", "test_output"); - // testOp(browser, "Extract dates", "test input", "test_output"); - // testOp(browser, "Extract domains", "test input", "test_output"); - // testOp(browser, "Extract EXIF", "test input", "test_output"); - // testOp(browser, "Extract email addresses", "test input", "test_output"); - // testOp(browser, "Extract file paths", "test input", "test_output"); - // testOp(browser, "Extract Files", "test input", "test_output"); - // testOp(browser, "Extract IP addresses", "test input", "test_output"); - // testOp(browser, "Extract LSB", "test input", "test_output"); - // testOp(browser, "Extract MAC addresses", "test input", "test_output"); - // testOp(browser, "Extract RGBA", "test input", "test_output"); - // testOp(browser, "Extract URLs", "test input", "test_output"); - // testOp(browser, "Filter", "test input", "test_output"); - // testOp(browser, "Find / Replace", "test input", "test_output"); - // testOp(browser, "Fletcher-16 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-32 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-64 Checksum", "test input", "test_output"); - // testOp(browser, "Fletcher-8 Checksum", "test input", "test_output"); - // testOp(browser, "Flip Image", "test input", "test_output"); - // testOp(browser, "Fork", "test input", "test_output"); - // testOp(browser, "Format MAC addresses", "test input", "test_output"); - // testOp(browser, "Frequency distribution", "test input", "test_output"); - // testOp(browser, "From BCD", "test input", "test_output"); - // testOp(browser, "From Base", "test input", "test_output"); - // testOp(browser, "From Base32", "test input", "test_output"); - // testOp(browser, "From Base58", "test input", "test_output"); - // testOp(browser, "From Base62", "test input", "test_output"); - // testOp(browser, "From Base64", "test input", "test_output"); - // testOp(browser, "From Base85", "test input", "test_output"); - // testOp(browser, "From Binary", "test input", "test_output"); - // testOp(browser, "From Braille", "test input", "test_output"); - // testOp(browser, "From Case Insensitive Regex", "test input", "test_output"); - // testOp(browser, "From Charcode", "test input", "test_output"); - // testOp(browser, "From Decimal", "test input", "test_output"); - // testOp(browser, "From HTML Entity", "test input", "test_output"); - // testOp(browser, "From Hex", "test input", "test_output"); - // testOp(browser, "From Hex Content", "test input", "test_output"); - // testOp(browser, "From Hexdump", "test input", "test_output"); - // testOp(browser, "From MessagePack", "test input", "test_output"); - // testOp(browser, "From Morse Code", "test input", "test_output"); - // testOp(browser, "From Octal", "test input", "test_output"); - // testOp(browser, "From Punycode", "test input", "test_output"); - // testOp(browser, "From Quoted Printable", "test input", "test_output"); - // testOp(browser, "From UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "GOST hash", "test input", "test_output"); - // testOp(browser, "Generate all hashes", "test input", "test_output"); - // testOp(browser, "Generate HOTP", "test input", "test_output"); - // testOp(browser, "Generate Image", "test input", "test_output"); - // testOp(browser, "Generate Lorem Ipsum", "test input", "test_output"); - // testOp(browser, "Generate PGP Key Pair", "test input", "test_output"); - // testOp(browser, "Generate QR Code", "test input", "test_output"); - // testOp(browser, "Generate TOTP", "test input", "test_output"); - // testOp(browser, "Generate UUID", "test input", "test_output"); - // testOp(browser, "Generic Code Beautify", "test input", "test_output"); - // testOp(browser, "Group IP addresses", "test input", "test_output"); - // testOp(browser, "Gunzip", "test input", "test_output"); - // testOp(browser, "Gzip", "test input", "test_output"); - // testOp(browser, "HAS-160", "test input", "test_output"); - // testOp(browser, "HMAC", "test input", "test_output"); - // testOp(browser, "HTML To Text", "test input", "test_output"); - // testOp(browser, "HTTP request", "test input", "test_output"); - // testOp(browser, "Hamming Distance", "test input", "test_output"); - // testOp(browser, "Haversine distance", "test input", "test_output"); - // testOp(browser, "Head", "test input", "test_output"); - // testOp(browser, "Heatmap chart", "test input", "test_output"); - // testOp(browser, "Hex Density chart", "test input", "test_output"); - // testOp(browser, "Hex to Object Identifier", "test input", "test_output"); - // testOp(browser, "Hex to PEM", "test input", "test_output"); - // testOp(browser, "Image Brightness / Contrast", "test input", "test_output"); - // testOp(browser, "Image Filter", "test input", "test_output"); - // testOp(browser, "Image Hue/Saturation/Lightness", "test input", "test_output"); - // testOp(browser, "Image Opacity", "test input", "test_output"); - // testOp(browser, "Index of Coincidence", "test input", "test_output"); - // testOp(browser, "Invert Image", "test input", "test_output"); - // testOp(browser, "JPath expression", "test input", "test_output"); - // testOp(browser, "JSON Beautify", "test input", "test_output"); - // testOp(browser, "JSON Minify", "test input", "test_output"); - // testOp(browser, "JSON to CSV", "test input", "test_output"); - // testOp(browser, "JWT Decode", "test input", "test_output"); - // testOp(browser, "JWT Sign", "test input", "test_output"); - // testOp(browser, "JWT Verify", "test input", "test_output"); - // testOp(browser, "JavaScript Beautify", "test input", "test_output"); - // testOp(browser, "JavaScript Minify", "test input", "test_output"); - // testOp(browser, "JavaScript Parser", "test input", "test_output"); - // testOp(browser, "Jump", "test input", "test_output"); - // testOp(browser, "Keccak", "test input", "test_output"); - // testOp(browser, "Label", "test input", "test_output"); - // testOp(browser, "Lorenz", "test input", "test_output"); - // testOp(browser, "Luhn Checksum", "test input", "test_output"); - // testOp(browser, "MD2", "test input", "test_output"); - // testOp(browser, "MD4", "test input", "test_output"); - // testOp(browser, "MD5", "test input", "test_output"); - // testOp(browser, "MD6", "test input", "test_output"); - // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "td", /Result snippet/); - // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:nth-of-type(1) td:nth-of-type(2)", "Result snippet"); - // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:eq(1) td:eq(1)", "test_output"); - // testOp(browser, "Mean", "test input", "test_output"); - // testOp(browser, "Median", "test input", "test_output");` - // testOp(browser, "Merge", "test input", "test_output");` - // testOp(browser, "Microsoft Script Decoder", "test input", "test_output"); - // testOp(browser, "Multiple Bombe", "test input", "test_output"); - // testOp(browser, "Multiply", "test input", "test_output"); - // testOp(browser, "NOT", "test input", "test_output"); - // testOp(browser, "Normalise Image", "test input", "test_output"); - // testOp(browser, "Normalise Unicode", "test input", "test_output"); - // testOp(browser, "Numberwang", "test input", "test_output"); - // testOp(browser, "OR", "test input", "test_output"); - // testOp(browser, "Object Identifier to Hex", "test input", "test_output"); - // testOp(browser, "Offset checker", "test input", "test_output"); - // testOp(browser, "Optical Character Recognition", "test input", "test_output"); - // testOp(browser, "PEM to Hex", "test input", "test_output"); - // testOp(browser, "PGP Decrypt", "test input", "test_output"); - // testOp(browser, "PGP Decrypt and Verify", "test input", "test_output"); - // testOp(browser, "PGP Encrypt", "test input", "test_output"); - // testOp(browser, "PGP Encrypt and Sign", "test input", "test_output"); - // testOp(browser, "PGP Verify", "test input", "test_output"); - // testOp(browser, "PHP Deserialize", "test input", "test_output"); - // testOp(browser, "Pad lines", "test input", "test_output"); - // testOp(browser, "Parse ASN.1 hex string", "test input", "test_output"); - // testOp(browser, "Parse colour code", "test input", "test_output"); - // testOp(browser, "Parse DateTime", "test input", "test_output"); - // testOp(browser, "Parse IP range", "test input", "test_output"); - // testOp(browser, "Parse IPv4 header", "test input", "test_output"); - // testOp(browser, "Parse IPv6 address", "test input", "test_output"); - // testOp(browser, "Parse ObjectID timestamp", "test input", "test_output"); - // testOp(browser, "Parse QR Code", "test input", "test_output"); - // testOp(browser, "Parse SSH Host Key", "test input", "test_output"); - // testOp(browser, "Parse TLV", "test input", "test_output"); - // testOp(browser, "Parse UDP", "test input", "test_output"); - // testOp(browser, "Parse UNIX file permissions", "test input", "test_output"); - // testOp(browser, "Parse URI", "test input", "test_output"); - // testOp(browser, "Parse User Agent", "test input", "test_output"); - // testOp(browser, "Parse X.509 certificate", "test input", "test_output"); - // testOp(browser, "Play Media", "test input", "test_output"); - // testOp(browser, "Power Set", "test input", "test_output"); - // testOp(browser, "Protobuf Decode", "test input", "test_output"); - // testOp(browser, "Pseudo-Random Number Generator", "test input", "test_output"); - // testOp(browser, "RC2 Decrypt", "test input", "test_output"); - // testOp(browser, "RC2 Encrypt", "test input", "test_output"); - // testOp(browser, "RC4", "test input", "test_output"); - // testOp(browser, "RC4 Drop", "test input", "test_output"); - // testOp(browser, "RIPEMD", "test input", "test_output"); - // testOp(browser, "ROT13", "test input", "test_output"); - // testOp(browser, "ROT47", "test input", "test_output"); - // testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output"); - // testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output"); - // testOp(browser, "Randomize Colour Palette", "test input", "test_output"); - // testOp(browser, "Raw Deflate", "test input", "test_output"); - // testOp(browser, "Raw Inflate", "test input", "test_output"); - // testOp(browser, "Register", "test input", "test_output"); - // testOp(browser, "Regular expression", "test input", "test_output"); - // testOp(browser, "Remove Diacritics", "test input", "test_output"); - // testOp(browser, "Remove EXIF", "test input", "test_output"); - // testOp(browser, "Remove line numbers", "test input", "test_output"); - // testOp(browser, "Remove null bytes", "test input", "test_output"); - // testOp(browser, "Remove whitespace", "test input", "test_output"); - // testOp(browser, "Render Image", "test input", "test_output"); - // testOp(browser, "Render Markdown", "test input", "test_output"); - // testOp(browser, "Resize Image", "test input", "test_output"); - // testOp(browser, "Return", "test input", "test_output"); - // testOp(browser, "Reverse", "test input", "test_output"); - // testOp(browser, "Rotate Image", "test input", "test_output"); - // testOp(browser, "Rotate left", "test input", "test_output"); - // testOp(browser, "Rotate right", "test input", "test_output"); - // testOp(browser, "SHA0", "test input", "test_output"); - // testOp(browser, "SHA1", "test input", "test_output"); - // testOp(browser, "SHA2", "test input", "test_output"); - // testOp(browser, "SHA3", "test input", "test_output"); - // testOp(browser, "SQL Beautify", "test input", "test_output"); - // testOp(browser, "SQL Minify", "test input", "test_output"); - // testOp(browser, "SSDEEP", "test input", "test_output"); - // testOp(browser, "SUB", "test input", "test_output"); - // testOp(browser, "Scan for Embedded Files", "test input", "test_output"); - // testOp(browser, "Scatter chart", "test input", "test_output"); - // testOp(browser, "Scrypt", "test input", "test_output"); - // testOp(browser, "Series chart", "test input", "test_output"); - // testOp(browser, "Set Difference", "test input", "test_output"); - // testOp(browser, "Set Intersection", "test input", "test_output"); - // testOp(browser, "Set Union", "test input", "test_output"); - // testOp(browser, "Shake", "test input", "test_output"); - // testOp(browser, "Sharpen Image", "test input", "test_output"); - // testOp(browser, "Show Base64 offsets", "test input", "test_output"); - // testOp(browser, "Show on map", "test input", "test_output"); - // testOp(browser, "Sleep", "test input", "test_output"); - // testOp(browser, "Snefru", "test input", "test_output"); - // testOp(browser, "Sort", "test input", "test_output"); - // testOp(browser, "Split", "test input", "test_output"); - // testOp(browser, "Split Colour Channels", "test input", "test_output"); - // testOp(browser, "Standard Deviation", "test input", "test_output"); - // testOp(browser, "Streebog", "test input", "test_output"); - // testOp(browser, "Strings", "test input", "test_output"); - // testOp(browser, "Strip HTML tags", "test input", "test_output"); - // testOp(browser, "Strip HTTP headers", "test input", "test_output"); - // testOp(browser, "Subsection", "test input", "test_output"); - // testOp(browser, "Substitute", "test input", "test_output"); - // testOp(browser, "Subtract", "test input", "test_output"); - // testOp(browser, "Sum", "test input", "test_output"); - // testOp(browser, "Swap endianness", "test input", "test_output"); - // testOp(browser, "Symmetric Difference", "test input", "test_output"); - // testOp(browser, "Syntax highlighter", "test input", "test_output"); - // testOp(browser, "TCP/IP Checksum", "test input", "test_output"); - // testOp(browser, "Tail", "test input", "test_output"); - // testOp(browser, "Take bytes", "test input", "test_output"); - // testOp(browser, "Tar", "test input", "test_output"); - // testOp(browser, "Text Encoding Brute Force", "test input", "test_output"); - // testOp(browser, "To BCD", "test input", "test_output"); - // testOp(browser, "To Base", "test input", "test_output"); - // testOp(browser, "To Base32", "test input", "test_output"); - // testOp(browser, "To Base58", "test input", "test_output"); - // testOp(browser, "To Base62", "test input", "test_output"); - // testOp(browser, "To Base64", "test input", "test_output"); - // testOp(browser, "To Base85", "test input", "test_output"); - // testOp(browser, "To Binary", "test input", "test_output"); - // testOp(browser, "To Braille", "test input", "test_output"); - // testOp(browser, "To Camel case", "test input", "test_output"); - // testOp(browser, "To Case Insensitive Regex", "test input", "test_output"); - // testOp(browser, "To Charcode", "test input", "test_output"); - // testOp(browser, "To Decimal", "test input", "test_output"); - // testOp(browser, "To HTML Entity", "test input", "test_output"); - // testOp(browser, "To Hex", "test input", "test_output"); - // testOp(browser, "To Hex Content", "test input", "test_output"); - // testOp(browser, "To Hexdump", "test input", "test_output"); - // testOp(browser, "To Kebab case", "test input", "test_output"); - // testOp(browser, "To Lower case", "test input", "test_output"); - // testOp(browser, "To MessagePack", "test input", "test_output"); - // testOp(browser, "To Morse Code", "test input", "test_output"); - // testOp(browser, "To Octal", "test input", "test_output"); - // testOp(browser, "To Punycode", "test input", "test_output"); - // testOp(browser, "To Quoted Printable", "test input", "test_output"); - // testOp(browser, "To Snake case", "test input", "test_output"); - // testOp(browser, "To Table", "test input", "test_output"); - // testOp(browser, "To UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "To Upper case", "test input", "test_output"); - // testOp(browser, "Translate DateTime Format", "test input", "test_output"); - // testOp(browser, "Triple DES Decrypt", "test input", "test_output"); - // testOp(browser, "Triple DES Encrypt", "test input", "test_output"); - // testOp(browser, "Typex", "test input", "test_output"); - // testOp(browser, "UNIX Timestamp to Windows Filetime", "test input", "test_output"); - // testOp(browser, "URL Decode", "test input", "test_output"); - // testOp(browser, "URL Encode", "test input", "test_output"); - // testOp(browser, "Unescape string", "test input", "test_output"); - // testOp(browser, "Unescape Unicode Characters", "test input", "test_output"); - // testOp(browser, "Unique", "test input", "test_output"); - // testOp(browser, "Untar", "test input", "test_output"); - // testOp(browser, "Unzip", "test input", "test_output"); - // testOp(browser, "VarInt Decode", "test input", "test_output"); - // testOp(browser, "VarInt Encode", "test input", "test_output"); - // testOp(browser, "View Bit Plane", "test input", "test_output"); - // testOp(browser, "Vigenère Decode", "test input", "test_output"); - // testOp(browser, "Vigenère Encode", "test input", "test_output"); - // testOp(browser, "Whirlpool", "test input", "test_output"); - // testOp(browser, "Windows Filetime to UNIX Timestamp", "test input", "test_output"); - // testOp(browser, "XKCD Random Number", "test input", "test_output"); - // testOp(browser, "XML Beautify", "test input", "test_output"); - // testOp(browser, "XML Minify", "test input", "test_output"); - // testOp(browser, "XOR", "test input", "test_output"); - // testOp(browser, "XOR Brute Force", "test input", "test_output"); - // testOp(browser, "XPath expression", "test input", "test_output"); - // testOp(browser, "YARA Rules", "test input", "test_output"); - // testOp(browser, "Zip", "test input", "test_output"); - // testOp(browser, "Zlib Deflate", "test input", "test_output"); - // testOp(browser, "Zlib Inflate", "test input", "test_output"); - }); + "Sanity check operations": async browser => { + const Images = await import("../samples/Images.mjs"); + testOp(browser, "A1Z26 Cipher Decode", "20 5 19 20 15 21 20 16 21 20", "testoutput"); + testOp(browser, "A1Z26 Cipher Encode", "test input", "20 5 19 20 9 14 16 21 20"); + testOp(browser, "ADD", "test input", "Ê»ÉÊv¿ÄÆËÊ", [{ "option": "Hex", "string": "56" }]); + testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }]); + testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]); + testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]); + testOp(browser, "Add line numbers", "test input", "1 test input"); + testOp(browser, ["From Hex", "Add Text To Image", "To Base64"], Images.PNG_HEX, Images.PNG_CHEF_B64, ["Chef", "Center", "Middle", 0, 0, 16]); + testOp(browser, "Adler-32 Checksum", "test input", "16160411"); + testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]); + testOp(browser, "Affine Cipher Encode", "test input", "njln rbfpn", [2, 1]); + testOp(browser, "Analyse hash", "0123456789abcdef", /CRC-64/); + testOp(browser, "Atbash Cipher", "test input", "gvhg rmkfg"); + // testOp(browser, "Avro to JSON", "test input", "test_output"); + // testOp(browser, "BLAKE2b", "test input", "test_output"); + // testOp(browser, "BLAKE2s", "test input", "test_output"); + // testOp(browser, "BSON deserialise", "test input", "test_output"); + // testOp(browser, "BSON serialise", "test input", "test_output"); + // testOp(browser, "Bacon Cipher Decode", "test input", "test_output"); + // testOp(browser, "Bacon Cipher Encode", "test input", "test_output"); + // testOp(browser, "Bcrypt", "test input", "test_output"); + // testOp(browser, "Bcrypt compare", "test input", "test_output"); + // testOp(browser, "Bcrypt parse", "test input", "test_output"); + // testOp(browser, "Bifid Cipher Decode", "test input", "test_output"); + // testOp(browser, "Bifid Cipher Encode", "test input", "test_output"); + // testOp(browser, "Bit shift left", "test input", "test_output"); + // testOp(browser, "Bit shift right", "test input", "test_output"); + testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]); + testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); + testOp(browser, ["From Hex", "Blur Image", "To Base64"], Images.PNG_HEX, Images.PNG_BLUR_B64); + // testOp(browser, "Bombe", "test input", "test_output"); + testOp(browser, "Bzip2 Compress", "test input", "BZh91AY&SYÏ........@..!N. .!.Â.À.3..ß.rE8P.Ï..."); + testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [true]); + // testOp(browser, "CRC-16 Checksum", "test input", "test_output"); + // testOp(browser, "CRC-32 Checksum", "test input", "test_output"); + // testOp(browser, "CRC-8 Checksum", "test input", "test_output"); + // testOp(browser, "CSS Beautify", "test input", "test_output"); + // testOp(browser, "CSS Minify", "test input", "test_output"); + // testOp(browser, "CSS selector", "test input", "test_output"); + // testOp(browser, "CSV to JSON", "test input", "test_output"); + // testOp(browser, "CTPH", "test input", "test_output"); + // testOp(browser, "Cartesian Product", "test input", "test_output"); + // testOp(browser, "Change IP format", "test input", "test_output"); + // testOp(browser, "Chi Square", "test input", "test_output"); + // testOp(browser, "CipherSaber2 Decrypt", "test input", "test_output"); + // testOp(browser, "CipherSaber2 Encrypt", "test input", "test_output"); + // testOp(browser, "Citrix CTX1 Decode", "test input", "test_output"); + // testOp(browser, "Citrix CTX1 Encode", "test input", "test_output"); + // testOp(browser, "Colossus", "test input", "test_output"); + // testOp(browser, "Comment", "test input", "test_output"); + // testOp(browser, "Compare CTPH hashes", "test input", "test_output"); + // testOp(browser, "Compare SSDEEP hashes", "test input", "test_output"); + // /testOp(browser, "Conditional Jump", "test input", "test_output"); + // testOp(browser, "Contain Image", "test input", "test_output"); + // testOp(browser, "Convert area", "test input", "test_output"); + // /testOp(browser, "Convert co-ordinate format", "test input", "test_output"); + // testOp(browser, "Convert data units", "test input", "test_output"); + // testOp(browser, "Convert distance", "test input", "test_output"); + // testOp(browser, "Convert Image Format", "test input", "test_output"); + // testOp(browser, "Convert mass", "test input", "test_output"); + // testOp(browser, "Convert speed", "test input", "test_output"); + // testOp(browser, "Convert to NATO alphabet", "test input", "test_output"); + // testOp(browser, "Count occurrences", "test input", "test_output"); + // testOp(browser, "Cover Image", "test input", "test_output"); + // testOp(browser, "Crop Image", "test input", "test_output"); + // testOp(browser, "DES Decrypt", "test input", "test_output"); + // testOp(browser, "DES Encrypt", "test input", "test_output"); + // testOp(browser, "DNS over HTTPS", "test input", "test_output"); + // testOp(browser, "Dechunk HTTP response", "test input", "test_output"); + // testOp(browser, "Decode NetBIOS Name", "test input", "test_output"); + // testOp(browser, "Decode text", "test input", "test_output"); + // testOp(browser, "Defang IP Addresses", "test input", "test_output"); + // testOp(browser, "Defang URL", "test input", "test_output"); + // testOp(browser, "Derive EVP key", "test input", "test_output"); + // testOp(browser, "Derive PBKDF2 key", "test input", "test_output"); + // testOp(browser, "Detect File Type", "test input", "test_output"); + // testOp(browser, "Diff", "test input", "test_output"); + // testOp(browser, "Disassemble x86", "test input", "test_output"); + // testOp(browser, "Dither Image", "test input", "test_output"); + // testOp(browser, "Divide", "test input", "test_output"); + // testOp(browser, "Drop bytes", "test input", "test_output"); + // testOp(browser, "Encode NetBIOS Name", "test input", "test_output"); + // testOp(browser, "Encode text", "test input", "test_output"); + // testOp(browser, "Enigma", "test input", "test_output"); + // testOp(browser, "Entropy", "test input", "test_output"); + // testOp(browser, "Escape string", "test input", "test_output"); + // testOp(browser, "Escape Unicode Characters", "test input", "test_output"); + // testOp(browser, "Expand alphabet range", "test input", "test_output"); + // testOp(browser, "Extract dates", "test input", "test_output"); + // testOp(browser, "Extract domains", "test input", "test_output"); + // testOp(browser, "Extract EXIF", "test input", "test_output"); + // testOp(browser, "Extract email addresses", "test input", "test_output"); + // testOp(browser, "Extract file paths", "test input", "test_output"); + // testOp(browser, "Extract Files", "test input", "test_output"); + // testOp(browser, "Extract IP addresses", "test input", "test_output"); + // testOp(browser, "Extract LSB", "test input", "test_output"); + // testOp(browser, "Extract MAC addresses", "test input", "test_output"); + // testOp(browser, "Extract RGBA", "test input", "test_output"); + // testOp(browser, "Extract URLs", "test input", "test_output"); + // testOp(browser, "Filter", "test input", "test_output"); + // testOp(browser, "Find / Replace", "test input", "test_output"); + // testOp(browser, "Fletcher-16 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-32 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-64 Checksum", "test input", "test_output"); + // testOp(browser, "Fletcher-8 Checksum", "test input", "test_output"); + // testOp(browser, "Flip Image", "test input", "test_output"); + // testOp(browser, "Fork", "test input", "test_output"); + // testOp(browser, "Format MAC addresses", "test input", "test_output"); + // testOp(browser, "Frequency distribution", "test input", "test_output"); + // testOp(browser, "From BCD", "test input", "test_output"); + // testOp(browser, "From Base", "test input", "test_output"); + // testOp(browser, "From Base32", "test input", "test_output"); + // testOp(browser, "From Base58", "test input", "test_output"); + // testOp(browser, "From Base62", "test input", "test_output"); + // testOp(browser, "From Base64", "test input", "test_output"); + // testOp(browser, "From Base85", "test input", "test_output"); + // testOp(browser, "From Binary", "test input", "test_output"); + // testOp(browser, "From Braille", "test input", "test_output"); + // testOp(browser, "From Case Insensitive Regex", "test input", "test_output"); + // testOp(browser, "From Charcode", "test input", "test_output"); + // testOp(browser, "From Decimal", "test input", "test_output"); + // testOp(browser, "From HTML Entity", "test input", "test_output"); + // testOp(browser, "From Hex", "test input", "test_output"); + // testOp(browser, "From Hex Content", "test input", "test_output"); + // testOp(browser, "From Hexdump", "test input", "test_output"); + // testOp(browser, "From MessagePack", "test input", "test_output"); + // testOp(browser, "From Morse Code", "test input", "test_output"); + // testOp(browser, "From Octal", "test input", "test_output"); + // testOp(browser, "From Punycode", "test input", "test_output"); + // testOp(browser, "From Quoted Printable", "test input", "test_output"); + // testOp(browser, "From UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "GOST hash", "test input", "test_output"); + // testOp(browser, "Generate all hashes", "test input", "test_output"); + // testOp(browser, "Generate HOTP", "test input", "test_output"); + // testOp(browser, "Generate Image", "test input", "test_output"); + // testOp(browser, "Generate Lorem Ipsum", "test input", "test_output"); + // testOp(browser, "Generate PGP Key Pair", "test input", "test_output"); + // testOp(browser, "Generate QR Code", "test input", "test_output"); + // testOp(browser, "Generate TOTP", "test input", "test_output"); + // testOp(browser, "Generate UUID", "test input", "test_output"); + // testOp(browser, "Generic Code Beautify", "test input", "test_output"); + // testOp(browser, "Group IP addresses", "test input", "test_output"); + // testOp(browser, "Gunzip", "test input", "test_output"); + // testOp(browser, "Gzip", "test input", "test_output"); + // testOp(browser, "HAS-160", "test input", "test_output"); + // testOp(browser, "HMAC", "test input", "test_output"); + // testOp(browser, "HTML To Text", "test input", "test_output"); + // testOp(browser, "HTTP request", "test input", "test_output"); + // testOp(browser, "Hamming Distance", "test input", "test_output"); + // testOp(browser, "Haversine distance", "test input", "test_output"); + // testOp(browser, "Head", "test input", "test_output"); + // testOp(browser, "Heatmap chart", "test input", "test_output"); + // testOp(browser, "Hex Density chart", "test input", "test_output"); + // testOp(browser, "Hex to Object Identifier", "test input", "test_output"); + // testOp(browser, "Hex to PEM", "test input", "test_output"); + // testOp(browser, "Image Brightness / Contrast", "test input", "test_output"); + // testOp(browser, "Image Filter", "test input", "test_output"); + // testOp(browser, "Image Hue/Saturation/Lightness", "test input", "test_output"); + // testOp(browser, "Image Opacity", "test input", "test_output"); + // testOp(browser, "Index of Coincidence", "test input", "test_output"); + // testOp(browser, "Invert Image", "test input", "test_output"); + // testOp(browser, "JPath expression", "test input", "test_output"); + // testOp(browser, "JSON Beautify", "test input", "test_output"); + // testOp(browser, "JSON Minify", "test input", "test_output"); + // testOp(browser, "JSON to CSV", "test input", "test_output"); + // testOp(browser, "JWT Decode", "test input", "test_output"); + // testOp(browser, "JWT Sign", "test input", "test_output"); + // testOp(browser, "JWT Verify", "test input", "test_output"); + // testOp(browser, "JavaScript Beautify", "test input", "test_output"); + // testOp(browser, "JavaScript Minify", "test input", "test_output"); + // testOp(browser, "JavaScript Parser", "test input", "test_output"); + // testOp(browser, "Jump", "test input", "test_output"); + // testOp(browser, "Keccak", "test input", "test_output"); + // testOp(browser, "Label", "test input", "test_output"); + // testOp(browser, "Lorenz", "test input", "test_output"); + // testOp(browser, "Luhn Checksum", "test input", "test_output"); + // testOp(browser, "MD2", "test input", "test_output"); + // testOp(browser, "MD4", "test input", "test_output"); + // testOp(browser, "MD5", "test input", "test_output"); + // testOp(browser, "MD6", "test input", "test_output"); + // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "td", /Result snippet/); + testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:{1} td:{2}", "Result snippet"); + // testOp(browser, "Mean", "test input", "test_output"); + // testOp(browser, "Median", "test input", "test_output");` + // testOp(browser, "Merge", "test input", "test_output");` + // testOp(browser, "Microsoft Script Decoder", "test input", "test_output"); + // testOp(browser, "Multiple Bombe", "test input", "test_output"); + // testOp(browser, "Multiply", "test input", "test_output"); + // testOp(browser, "NOT", "test input", "test_output"); + // testOp(browser, "Normalise Image", "test input", "test_output"); + // testOp(browser, "Normalise Unicode", "test input", "test_output"); + // testOp(browser, "Numberwang", "test input", "test_output"); + // testOp(browser, "OR", "test input", "test_output"); + // testOp(browser, "Object Identifier to Hex", "test input", "test_output"); + // testOp(browser, "Offset checker", "test input", "test_output"); + // testOp(browser, "Optical Character Recognition", "test input", "test_output"); + // testOp(browser, "PEM to Hex", "test input", "test_output"); + // testOp(browser, "PGP Decrypt", "test input", "test_output"); + // testOp(browser, "PGP Decrypt and Verify", "test input", "test_output"); + // testOp(browser, "PGP Encrypt", "test input", "test_output"); + // testOp(browser, "PGP Encrypt and Sign", "test input", "test_output"); + // testOp(browser, "PGP Verify", "test input", "test_output"); + // testOp(browser, "PHP Deserialize", "test input", "test_output"); + // testOp(browser, "Pad lines", "test input", "test_output"); + // testOp(browser, "Parse ASN.1 hex string", "test input", "test_output"); + // testOp(browser, "Parse colour code", "test input", "test_output"); + // testOp(browser, "Parse DateTime", "test input", "test_output"); + // testOp(browser, "Parse IP range", "test input", "test_output"); + // testOp(browser, "Parse IPv4 header", "test input", "test_output"); + // testOp(browser, "Parse IPv6 address", "test input", "test_output"); + // testOp(browser, "Parse ObjectID timestamp", "test input", "test_output"); + // testOp(browser, "Parse QR Code", "test input", "test_output"); + // testOp(browser, "Parse SSH Host Key", "test input", "test_output"); + // testOp(browser, "Parse TLV", "test input", "test_output"); + // testOp(browser, "Parse UDP", "test input", "test_output"); + // testOp(browser, "Parse UNIX file permissions", "test input", "test_output"); + // testOp(browser, "Parse URI", "test input", "test_output"); + // testOp(browser, "Parse User Agent", "test input", "test_output"); + // testOp(browser, "Parse X.509 certificate", "test input", "test_output"); + // testOp(browser, "Play Media", "test input", "test_output"); + // testOp(browser, "Power Set", "test input", "test_output"); + // testOp(browser, "Protobuf Decode", "test input", "test_output"); + // testOp(browser, "Pseudo-Random Number Generator", "test input", "test_output"); + // testOp(browser, "RC2 Decrypt", "test input", "test_output"); + // testOp(browser, "RC2 Encrypt", "test input", "test_output"); + // testOp(browser, "RC4", "test input", "test_output"); + // testOp(browser, "RC4 Drop", "test input", "test_output"); + // testOp(browser, "RIPEMD", "test input", "test_output"); + // testOp(browser, "ROT13", "test input", "test_output"); + // testOp(browser, "ROT47", "test input", "test_output"); + // testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output"); + // testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output"); + // testOp(browser, "Randomize Colour Palette", "test input", "test_output"); + // testOp(browser, "Raw Deflate", "test input", "test_output"); + // testOp(browser, "Raw Inflate", "test input", "test_output"); + // testOp(browser, "Register", "test input", "test_output"); + // testOp(browser, "Regular expression", "test input", "test_output"); + // testOp(browser, "Remove Diacritics", "test input", "test_output"); + // testOp(browser, "Remove EXIF", "test input", "test_output"); + // testOp(browser, "Remove line numbers", "test input", "test_output"); + // testOp(browser, "Remove null bytes", "test input", "test_output"); + // testOp(browser, "Remove whitespace", "test input", "test_output"); + // testOp(browser, "Render Image", "test input", "test_output"); + // testOp(browser, "Render Markdown", "test input", "test_output"); + // testOp(browser, "Resize Image", "test input", "test_output"); + // testOp(browser, "Return", "test input", "test_output"); + // testOp(browser, "Reverse", "test input", "test_output"); + // testOp(browser, "Rotate Image", "test input", "test_output"); + // testOp(browser, "Rotate left", "test input", "test_output"); + // testOp(browser, "Rotate right", "test input", "test_output"); + // testOp(browser, "SHA0", "test input", "test_output"); + // testOp(browser, "SHA1", "test input", "test_output"); + // testOp(browser, "SHA2", "test input", "test_output"); + // testOp(browser, "SHA3", "test input", "test_output"); + // testOp(browser, "SQL Beautify", "test input", "test_output"); + // testOp(browser, "SQL Minify", "test input", "test_output"); + // testOp(browser, "SSDEEP", "test input", "test_output"); + // testOp(browser, "SUB", "test input", "test_output"); + // testOp(browser, "Scan for Embedded Files", "test input", "test_output"); + // testOp(browser, "Scatter chart", "test input", "test_output"); + // testOp(browser, "Scrypt", "test input", "test_output"); + // testOp(browser, "Series chart", "test input", "test_output"); + // testOp(browser, "Set Difference", "test input", "test_output"); + // testOp(browser, "Set Intersection", "test input", "test_output"); + // testOp(browser, "Set Union", "test input", "test_output"); + // testOp(browser, "Shake", "test input", "test_output"); + // testOp(browser, "Sharpen Image", "test input", "test_output"); + // testOp(browser, "Show Base64 offsets", "test input", "test_output"); + // testOp(browser, "Show on map", "test input", "test_output"); + // testOp(browser, "Sleep", "test input", "test_output"); + // testOp(browser, "Snefru", "test input", "test_output"); + // testOp(browser, "Sort", "test input", "test_output"); + // testOp(browser, "Split", "test input", "test_output"); + // testOp(browser, "Split Colour Channels", "test input", "test_output"); + // testOp(browser, "Standard Deviation", "test input", "test_output"); + // testOp(browser, "Streebog", "test input", "test_output"); + // testOp(browser, "Strings", "test input", "test_output"); + // testOp(browser, "Strip HTML tags", "test input", "test_output"); + // testOp(browser, "Strip HTTP headers", "test input", "test_output"); + // testOp(browser, "Subsection", "test input", "test_output"); + // testOp(browser, "Substitute", "test input", "test_output"); + // testOp(browser, "Subtract", "test input", "test_output"); + // testOp(browser, "Sum", "test input", "test_output"); + // testOp(browser, "Swap endianness", "test input", "test_output"); + // testOp(browser, "Symmetric Difference", "test input", "test_output"); + // testOp(browser, "Syntax highlighter", "test input", "test_output"); + // testOp(browser, "TCP/IP Checksum", "test input", "test_output"); + // testOp(browser, "Tail", "test input", "test_output"); + // testOp(browser, "Take bytes", "test input", "test_output"); + // testOp(browser, "Tar", "test input", "test_output"); + // testOp(browser, "Text Encoding Brute Force", "test input", "test_output"); + // testOp(browser, "To BCD", "test input", "test_output"); + // testOp(browser, "To Base", "test input", "test_output"); + // testOp(browser, "To Base32", "test input", "test_output"); + // testOp(browser, "To Base58", "test input", "test_output"); + // testOp(browser, "To Base62", "test input", "test_output"); + // testOp(browser, "To Base64", "test input", "test_output"); + // testOp(browser, "To Base85", "test input", "test_output"); + // testOp(browser, "To Binary", "test input", "test_output"); + // testOp(browser, "To Braille", "test input", "test_output"); + // testOp(browser, "To Camel case", "test input", "test_output"); + // testOp(browser, "To Case Insensitive Regex", "test input", "test_output"); + // testOp(browser, "To Charcode", "test input", "test_output"); + // testOp(browser, "To Decimal", "test input", "test_output"); + // testOp(browser, "To HTML Entity", "test input", "test_output"); + // testOp(browser, "To Hex", "test input", "test_output"); + // testOp(browser, "To Hex Content", "test input", "test_output"); + // testOp(browser, "To Hexdump", "test input", "test_output"); + // testOp(browser, "To Kebab case", "test input", "test_output"); + // testOp(browser, "To Lower case", "test input", "test_output"); + // testOp(browser, "To MessagePack", "test input", "test_output"); + // testOp(browser, "To Morse Code", "test input", "test_output"); + // testOp(browser, "To Octal", "test input", "test_output"); + // testOp(browser, "To Punycode", "test input", "test_output"); + // testOp(browser, "To Quoted Printable", "test input", "test_output"); + // testOp(browser, "To Snake case", "test input", "test_output"); + // testOp(browser, "To Table", "test input", "test_output"); + // testOp(browser, "To UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "To Upper case", "test input", "test_output"); + // testOp(browser, "Translate DateTime Format", "test input", "test_output"); + // testOp(browser, "Triple DES Decrypt", "test input", "test_output"); + // testOp(browser, "Triple DES Encrypt", "test input", "test_output"); + // testOp(browser, "Typex", "test input", "test_output"); + // testOp(browser, "UNIX Timestamp to Windows Filetime", "test input", "test_output"); + // testOp(browser, "URL Decode", "test input", "test_output"); + // testOp(browser, "URL Encode", "test input", "test_output"); + // testOp(browser, "Unescape string", "test input", "test_output"); + // testOp(browser, "Unescape Unicode Characters", "test input", "test_output"); + // testOp(browser, "Unique", "test input", "test_output"); + // testOp(browser, "Untar", "test input", "test_output"); + // testOp(browser, "Unzip", "test input", "test_output"); + // testOp(browser, "VarInt Decode", "test input", "test_output"); + // testOp(browser, "VarInt Encode", "test input", "test_output"); + // testOp(browser, "View Bit Plane", "test input", "test_output"); + // testOp(browser, "Vigenère Decode", "test input", "test_output"); + // testOp(browser, "Vigenère Encode", "test input", "test_output"); + // testOp(browser, "Whirlpool", "test input", "test_output"); + // testOp(browser, "Windows Filetime to UNIX Timestamp", "test input", "test_output"); + // testOp(browser, "XKCD Random Number", "test input", "test_output"); + // testOp(browser, "XML Beautify", "test input", "test_output"); + // testOp(browser, "XML Minify", "test input", "test_output"); + // testOp(browser, "XOR", "test input", "test_output"); + // testOp(browser, "XOR Brute Force", "test input", "test_output"); + // testOp(browser, "XPath expression", "test input", "test_output"); + // testOp(browser, "YARA Rules", "test input", "test_output"); + // testOp(browser, "Zip", "test input", "test_output"); + // testOp(browser, "Zlib Deflate", "test input", "test_output"); + // testOp(browser, "Zlib Inflate", "test input", "test_output"); }, diff --git a/tests/operations/tests/Image.mjs b/tests/operations/tests/Image.mjs index 2ca363b8..1f450433 100644 --- a/tests/operations/tests/Image.mjs +++ b/tests/operations/tests/Image.mjs @@ -9,7 +9,7 @@ * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; -import { GIF_ANIMATED_HEX, PNG_HEX, JPG_B64, EXIF_JPG_HEX, NO_EXIF_JPG_HEX } from "../samples/Images.mjs"; +import { GIF_ANIMATED_HEX, PNG_HEX, JPG_B64, EXIF_JPG_HEX, NO_EXIF_JPG_HEX } from "../../samples/Images.mjs"; TestRegister.addTests([ { diff --git a/tests/operations/tests/Magic.mjs b/tests/operations/tests/Magic.mjs index 3ae143d2..24353565 100644 --- a/tests/operations/tests/Magic.mjs +++ b/tests/operations/tests/Magic.mjs @@ -7,7 +7,7 @@ * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; -import { JPG_RAW } from "../samples/Images.mjs"; +import { JPG_RAW } from "../../samples/Images.mjs"; TestRegister.addTests([ { diff --git a/tests/operations/tests/PGP.mjs b/tests/operations/tests/PGP.mjs index 9748f937..8df05fe9 100644 --- a/tests/operations/tests/PGP.mjs +++ b/tests/operations/tests/PGP.mjs @@ -6,7 +6,7 @@ * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; -import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../samples/Ciphers.mjs"; +import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../../samples/Ciphers.mjs"; // RSA-1024 const ALICE_PRIVATE = `-----BEGIN PGP PRIVATE KEY BLOCK----- diff --git a/tests/operations/tests/RSA.mjs b/tests/operations/tests/RSA.mjs index 33e7139f..42bc7246 100644 --- a/tests/operations/tests/RSA.mjs +++ b/tests/operations/tests/RSA.mjs @@ -6,7 +6,7 @@ * @license Apache-2.0 */ import TestRegister from "../../lib/TestRegister.mjs"; -import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../samples/Ciphers.mjs"; +import {ASCII_TEXT, UTF8_TEXT, ALL_BYTES} from "../../samples/Ciphers.mjs"; const PEM_PRIV_2048 = `-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAwfaUOpUEutKyU3wkCv6kYunz4MqxzSuTSckRz1IxwZtwIiqq diff --git a/tests/operations/samples/Ciphers.mjs b/tests/samples/Ciphers.mjs similarity index 100% rename from tests/operations/samples/Ciphers.mjs rename to tests/samples/Ciphers.mjs diff --git a/tests/operations/samples/Images.mjs b/tests/samples/Images.mjs similarity index 90% rename from tests/operations/samples/Images.mjs rename to tests/samples/Images.mjs index 396e9f7d..c9aff915 100644 --- a/tests/operations/samples/Images.mjs +++ b/tests/samples/Images.mjs @@ -22,7 +22,13 @@ export const PNG_HEX = "89504e470d0a1a0a0000000d49484452000000200000002008060000 * The CyberChef logo with 'chef' * 32x32 */ -export const PNG_CHEF_HEX = "89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af4000006e4494441547801a5c17d6c947701c0f1efeff73cf7debbbed0d2a3c7515e5ae81bd1c2601bd0256685e29808a84c9bc00cfec14b8448b205636234997f2ca8c1f9075163c8d61582246b9913df161184a6c46a24a3a1b4bb513aeee8fb95bb722fcf5def797c6a21e5e55abaf9f9083e1fa5b9b9b9c6ebf5ae4b24124a3018bcb27ffffeff003a200103d09903c1dc084002c6c183073dfbf6edfb555e5ede37a2d128b1584c0246341afd606c6ceca3a2a2a22d9aa65ddbb871e31e20c353a8cc4eb4b4b43cbb7cf9f203369bad4ad7f518e070bbdd6b98a23345783c9ead6eb7fb2bc264b3d9caac56ebf79a9a9abe64b7db0bb66ddb7602d0c9423033d1d6d67660f1e2c5c7841016b28844227a2c169364914c266fdb6c361fa66030b867fbf6edef9085ca0c5a5a5a9e292d2d3d2684b0f039d8ed763f530c5dd79989243b515e5ebe5f4a69e1ffa469dad0ae5dbbce02822c14b2530e1f3efc03abd5ea6316a9548a542a259885aaaa39df32eddcb9d3dfdcdcfc218f51c9ce3025793ac11cd8edf6d24c26f33c20810c0f9164a7c762b18b3c9dc11c689a164a24121d80ce631466b068d1a2ae9a9a9a464551dcdc97c964300c0329259392c9a4914ea705b3d0346da8a1a1a1eac48913bf070ca6496081c2a316017540d5f9f3e78b2a2b2bff585a5aba5a55d579985a5b5b0904025454543049d334239d4e0b66a1aaaaabbebebeeff4e9d31d4c73027b81f592699b815701158803b97bf7ee5d5557577748d7f534264551501485b9482412bd8661640cc3d04d291eb50e70026fa94c59013c0b9c006e33ad2e140a6d8d442296fcfc7ce62a93c9c45f78e185d5274f9eac733a9d453b76ec789b47f9818f8188ca94e7804ee0368ffa27f0b54020c09a356b7820994cd2dddd4d2412910e87039fcfc7c3344dd30dc358d1d8d83804dc649a0aac053c80049e9380022c003ee5491a70b4baba9a07464646686e6ea6b7b7974020c0b973e7e8eeeee681f1f171ce9e3d9b036c0096029b80ef00164001ca003b900f2c530107e00286c92e62b7db53801553341aa5b1b191c2c242229188ded2d2223b3b3b59b16205932e5fbe8ccbe5c2741c88032e601fb01ab80234017b8061e00395290230c82ed1d6d6f637b7dbfde5bebe3ea49404834182c12077eedc21180c12080470b95c4c4c4c70e1c2052a2b2b3b8134a00049e026b014b8c23481490574200338c9ce52565656ae280a797979a8aa4a49490993ac562be17098bb77ef525151c1c0c000f3e7cfa7bfbfbf0678134833450706c94205e24014980f74f190aa62977d7da5ffd4e0bfff5ae62b2e428cf4225405d1f72f1c050b8d5c87db4824128c8e8ed2d3d36384c361313232426d6d2d757575572e5dbaf427a6e96421997203a80604d3e4d76b4b7e674875bbd1db810c5c420cde400c7421039729713a854b5184896030487b7bbbe8eaea22180cd2d1d1416e6eeec98686061f700f880371b2904c69030a8097012ba6576abd55b7c7e25b0d2d8eb7681e0f24523a0b9ed981abb094496eb71bdf721f5abe8694128fc743381c46d7f54fc2a6fafafa9552ca5dc02ab2509892046e016b804d409dd7637ba3c065295ce97550d7f8238a2bd6f1c63b2d8cbbfd2c29aba1b8a0806bd7af33343e2edeed7f17e72b4e6ad7d6b279f9662c160b3d3d3d85baaebfae69dafe850b17e68442a15f02134c5905c4816e856911a003b8feedb5beb117cb0b5e2b2b744a4c351bb6e329282692d0f83418e49b2fbd8448a709f4f60ae976b3e0f905b4c5dad8e6d986dfeea7a4a4243c3a3a7ab7b8b8d85d5c5c4c6e6eeef16bd7ae5d62da2de026905279d2f02a9ffb87393645e5318776efe6d0eedd64749dd8c00093a2d128f5f3eaa9cfa98704ff63b3d9462391c86b3e9feffd582cf6db53a74efd82478d719fe449d2a28a55cc42d334ecaacaa4d1d1511ea7ebbaccc9c9d980c966b3addfb469d31266207992a1eb0c320b9bcd460a931046341ac5300c1e964c26977a3c9ed731a9aa5ae9f57abfcb0c549e640cdf4bfdda69757c550814b250a4c4555444f9ca9548af1721048f11a954ea6a341afd89dbedde1a0a858e3103952c7efc974f3e7cf3e5f203f373ac3f053cdca7eb3aa1681497c381a2aa7c74e386f8f3850bc6c4c4042e972bb365cb16c52430a5d3e9bfb7b6b6be07bcc72c54b233beff878f7fb3f38bdef797cc736c56ad8eb7805c29255e8783a14080c4e82899c141c3eff71b252525f8fd7e45983059add6dba150e8e7cc81ca2cce5c1d18049a760f0d6b654ed7cfac168bcf62b3e1abae6652babfdfc81b1e963c2493c9dc89c7e3072f5ebc18620e14e6e0785353a7aeeb6f572c5b366eb35a17ab8a928f69e4de3d632c1e179832994c301e8f1f6b6f6f7ff5c89123579923c16724a5b4fee3cc99aad2850bbf702b1ccebd393c7ccfd479f4e8d1ab7d7d7d293ea3ff02d269af2f0fa7289f0000000049454e44ae426082"; +export const PNG_CHEF_B64 = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAH40lEQVR4AaXBfVAU5wEH4N/77t7ufXAnHlwE5MuK1uApVo1ppNBxgpJKKyijaewYJzRj0eokjBpbp3HQ0VpN1fqHndCxNkW4UWf8KHZaa0yR1hPH04QGGwm9Ata7KN/c5m5v9+52t8tIp1QPJOnzEHw5TF1dnTMlJWVxOBxmfD7fjY0bN34EQAVAAWgAVEwAwcQQABSAtmXLFltlZeW7iYmJqwVBQCgUogA0QRAuDg4OfuxwOEpkWW5dunRpBQAFT8FifOTcuXPPz5w5cxPP87mqqoYAmKxW63N4RMUjxGazrbBard8hOp7ncziOe7O2tnaJ0Wi0l5WVnQCgIg6CsRG3270pOzv7CCHEgDgCgYAaCoUo4pAk6T7P81Oh8/l8FStXrvwt4mAxhnPnzi3Myso6Qggx4EswGo0ZeERTVRVjoYiPzJgxYyOl1ID/kyzLPevWrbsAgCAOBvExVVVVOzmOm4pxRCIRRCIRgnGwLJvwim7NmjUZdXV17+MxLOLTdBKejmACjEZjlqIoLwCgABSMQhGfGgqFmvB0GiZAlmV/OBz2AFDxGAZjyMzMvOt0OtcyDGPFiEgkAkVRwDAMhkmSpEWjUYJxyLLcU1xcnHvixIkGABpGEEIM6enpLxCMkpOT82JpaenLHMc9IwiCv6CgoG3RokWbjUbjTOh4nofX60VGRgaGBQIBNRQKUTyFz+fbWFZW9i5GmM3m9IaGhsb8/PxsihHbtm071traeikpKYnz+/2fLFiwILu8vPwXBw4cOK+qahQ6RVGgaRomIhwOd2qapmiapuoiGKWiomJbZmbm5OTk5K+y0BUUFHx33759P8jLy1vW1tb2Z+hqa2vR3Ny87/Dhwzs7OjrgcDgwUYqiiIWFhQvq6+sLzGazY9WqVe9hlPLy8rzTp097QqFQBwPd3r17a65evfo3l8u1H6O0tbW17t69e3t7ezvsdjsopRgcHITZbEYoFMLQ0BCRJAkcx2E0SZKI3+9/0NXVNd3j8fR1dna2K4oSYxjGuH79+h8WFxcXWSwWo8Fg4BldQk1NzaHjx4//+s6dOzcwSjQaFevr6z+orKys4DgOlFLwPA+bzQZVVWGz2TB37lx4vV5wHIdhQ0NDcDqddP78+Xmpqal07dq1r5WUlKw6pSOEsOvWrdvtdDqn2e1229DQUCLL83xCcnKy2e/3P0QcXq/3I5PJFAHAQWe329HV1YXk5GQEAgH19u3b1OFwQBRFaJoGq9WKvr4+LF68+NlYLCZYrdYUj8fTunz58sqGhoZ3qqqqlsybN6/x8uXLgf3795dRAAQ6RVFUxBd2u90ftLS0QBAEeDwe+Hw+tLS0wO12w+PxIC0tDZcuXcLFixexcOFCnDp1CoqiRAkhfDAYHLxy5cq1/Pz8ZRiFUkqgY1VVVaBLSkqyIj5DTk7ODIZhYDQaYTAYkJSUhGEcx6Gvrw8Mw2DWrFkQRRGUUlRXV6O6ulrEKC6X60PEwcqyPHD37t3eaTo8JneKxfjW1jdD/X9vplMmGQHL10Gkz0EG22Gyp2uTTFbtQTQKTdPQ3t6uASDQ7dq1C263u+rmzZt/xIhYLCYjDqppWuzChQt/WLFixcuUUh7/Rb//0iLP+u17qfbwLqj3ryChASAcAPVeQ5rZTCwMQ6BTVRXNzc3k+vXriMVi0DQNZrP5YH5+PoLB4KeiKHZIktSFOCh0R48e/emcOXNSt27desxoNCZC99o3Zy158fUfO1uuN8LORPAfiqohdeEqWJKzMMxkMoFSCnmyDEIIampqsGHDBjgcDjqgW758+WKXy3WpqKhoC+Jgoevu7m4vLCz81smTJ3+zZ8+eXlEUowkWs+nTm024VrMTqzcfgsXE48N+AYMw45MBBc+lyrjf2UlgMCBGYugv70chWwj+Mx49PT2oqalhJEnq4TgObrcbN27ceBVxEIxCCGHT09Odq/JSv+ZMZk8YIgKkmIrVb52A3ZGK42fP4tqtW9j7xhuwMAyabt2CYDKhK7MLxx4ew9uOt5EdzkYwGBxobGy0chxngG5gYGCby+U6hBFTpkyZJkmSEggE/sXgf6mCIDz83mxrhZlGn4cupmqYnV8Kk8WK+bm5KCsqgsVsRkwQ0NndjR5RRK4lF6VcKRJjiRhGCPE1NTW9brFYXhEE4bjL5foJAA0jQqHQkCzLAegonkQNLJmPcciyDCPLYlh/fz8ep6oqTUhI+AZ0PM/nL1u2bBrGQPEkTVXRjXHwPI8IdIRogiBA0zSMJknSV2w223boWJZ9NiUlZTPGwOJJWm8wUmPmTKWEgEEcDKWwOByYMWcOaEoKCCF4DIlEIi2CIOy1Wq0r/H7/EYyBRRzVf/rn+z/79oxNzyRw7wCwYYSqqvALAiwmExiWxcdtbeTS1ataLBaDxWJRSkpKGB2BLhqNNp4/f/4sgLMYB4v4tB/9/h+/WjMv5XfTkkwvsZzpKIBJlFKkmEzo8XoR7u+H0t2tZWRkaGlpacjIyGCIDjqO4+77/f5DmAAW4zjT8rAbQO2rPb1yjtnyc85gmGrgeUydPRvDog8eaIm9vRSjKIrymSiKW5qamvyYAAYT8Mva2juqqr43a/r0z3mOy2YZZjJ0fcGgNiiKBDpFUXyiKB5pbm5ev2PHjhZMEMEXRCnl/nLmTG5Wenpe18DApI7e3qDuzsGDB1vu3bsXwRf0bxUQXc2aUJWHAAAAAElFTkSuQmCC"; + +/** + * The CyberChef logo with blur + * 32x32 + */ +export const PNG_BLUR_B64 = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAANT0lEQVR4AS3BC5CV1X0A8P8553s/7mMvyz5gWUFApEKpEtloSQdLDDDoREXMDK1Zx8dg4xjHqdWpQwgI29QoFrE6gyFJ6YhmoDNMapIBYhzHqgg1ZAvRdIVld5Vl9+597N17v+8779NNJ78fklL6GzdutJ955hnnrbfect98803vxIkTwccffxwdOnQoGhoaihuNRiilDKvValCr1XzGmNtqtdz29naru7sburq6dG9vr1i6dClbtWoV7evryzZv3pw8/PDDSX9/f+vIkSPN/fv3t86cOZMYY7KBgQFarVY5AAjr4MGD6KOPPsK1Wg0bY4ht25Y9q1gs2h0dHW6apm5PT4/HGPMrlYpv23aQJIk3y8nn85bneYgQopVSglJq1et1Mjk5iS5fvqzPnz+vzp49K44fP85uueUW++jRozalVDz77LOkUCjg/v5+hI8dO4YajQZSSuE0TYnW2rJneZ7nlEolt7293SuVSn5nZ6ff1tYWtrW1hcViMczn81EYhpHjOBFCKNJah5TSsNVqBZVKJRgdHQ0uXLjgnzt3znv77bfdo0ePOkeOHLEPHTpkHThwgKxbt46sWLECk4sXL3ozMzPWmTNnnEaj4QwPD3vbt2/3a7VaeOXKlVBKGRFCIsdxIilluGPHjnDXrl0BQsh3Xdf3PM8dGBiwXNe1fN/Hvu8jz/MgjmP98ssvq3379qkoiuTrr78ub731VvHhhx+qbdu2qf7+frV69WqNq9UqmpycxK7rYtu2ied5VhAEdj6ftwuFglssFr1SqeTncrkgn88HuVwuCMMwCsMw8jwvtCwrJISExpiQcx6maRq0Wi2/Uqn4X375pTcyMuIODg46586ds9977z373LlzZHx8HJ8+fRoXCgVEDh486D755JN2uVx2xsfH3eHhYf+JJ57wa7VaVC6XIyFERAiJACBijEWMscgYE+zcuTPYs2ePZ9u2Y9u25TgOdl0XeZ4HnufpKIpUHMfqtddeEwMDA2LZsmX85MmTYnx8XGit5djYmHznnXcUNsagKIqQbdvYsixSKBRIGIZWGIZ2oVBwCoWCm8vlvCiK/GBWGIbBrDAIgtBxnJAQEgJAqJQKpZQB59xPksRvNptuvV53JiYmnMuXL9vDw8PW+Pg4GRoaIrVaDc+dOxeVSiWE169fD3PnzkVdXV2oVCqhfD6P4zgm+Xye5PN5K45jO5fLObNcjLFHCPEAwEMIeUopXwjhc869LMu8VqvlzszMOI1Gw6nX6061WrUbjYY1PT1Nrl69SkZGRvDZs2fxBx98gF599VX0/vvvg3XvvffCyMgILFiwADzPQ/l8HsVBgKMowgBAQGsiGLNZltmcMZtS6lBKXZplLmXMUlIiTDC2bQdmScdx7DiOSZqmmDGG0zTFjDEkhEBSSlQqlaC3txd6e3vhtttuA7xo/U3w1W+uN/kFeQgLIfixBcR3QAFHQDQSWmHGKU7ThCRJy8rS1Mqy1KKUWlma2hmlVpZRizFGKKWEMYYZpVgIgYQQIIQwWmswsxhjptFomMnJSTMxMWFGR0cN/un3vmX65gLc3NtrlnTnTGQBBJYCDzT4WANIhjRniGUJZlmGGU0Jp5QwmhEhOBaMYc4Z5oxhKTkSgiMuBCiljBDCKKU0xlgbY7SUUgshtBBC53I5PTg4aPC2mwEe2txjruuYhqXzjJmf12ZOwE3B48ZDythGGC0YSEpB8AxxRpHgDEkhkOQcCcmRFAIJKUBKZaSURv8JIUTZtq3iOFBxHKv29nbl+77u7OzU9XrdvPTSSxofe+4ec20nwI2LPFOEFnQEyrR5yoRYGFdnAJKB4RQES0EyCkowkIKDksJIJY1S0mgltdZSKyW11koBAomQkRiDJDaRYZyTxWJRBkGg2tvblW3buqurS1+6dMngB5ZWIPnlHLN9QwPuukmba4t1mAMzUCDceIoZWzEDghkpqJGcghLCKMGNUsJoKYxWSisttVZaaa2UBiOVlkoDSESIAAAZBZG0bVs5gaOKxaJatmyZWrBggR4YGND4ujv/F368+HO4zxuBlfAFdMsyBGwSSFIFyJogswaIrAkqS0FxaiSnoJUwWnKjlDBKCaOU0lJJrZTUUkqt1Syp/h8QkEEcSMdxlOu6KteeU8YY3dHRoc+cOWPw/i9+jrak/42+VZiG7mQUdcsy5NIKqOkJBHQadNYEmTaBpy0ksxRpRkEwiiQXoIQwUgijpDBKcCOl1FJyLaVUUnOllFCUUi200MY1iraoHjo/ZJIk0fPnz9eHDx/W+HH/12gd/gA5w+/iztZFBONDmE2N4GxyDNPaBGb1Ck4bVcyTJhI0QYJlSHEKklOkBAfJOXDOQChhhOBGcGY4Zyaj1LSyluFZpgFAN5tNM1GdMIwxff78efPuu++aU6dOgfVt979QbvBXeKU8iMbGz2OYvIhVdQyLX43jrDpJ0ukqyWamMU9nMM+qmNMUS8aQ5BQJqZAEZLAhIAgBJhhwLkxKU6BZZrI0MzNJYrjgZmZmxkxVpsyJ/zwBr7zyCnz66adw3333GXz29ZfwzewjhC++jxuffkySkQskHf2cVL8Ytmh9ktDpCskadUJbM0RkCRY0xZJnWAqOpOBIco6E5CAEA8E4MMaAMgpZlkCz2YR6ow6N6QZUK1UYGx2Der1uyq2y4ZybO+64A/BN079GldO/wJfOvEPY+CCuj1wg5dE/WDMTo2RmatLKGjXCZupEZgmWNMWKUywZw5JzrKRASnKkhEBCCCQlBy4yxBmFJElQo9lA1WoVVWtlNDE5AZ999hkc/tlh9MjfPIKGhobQ7t27AV/+xXEMnw3i4MolTEcvEqt2FaNqGbNKhdBalfCZBmFZiwhKsRQcGyGRURIZJUEribRWoLQGrRVorUAqDZxzxIWAjGbQSmZQlmZQmaqgNE2h2WxCpVKBsbExGB8fB3wDrqP6l5/hrDqC82wa6Zk6pq0Gps0ZTFtNLFmGNOfIaIlAKQBjAAEYBAaQAYMAGYSMQQjMHwFoAwBGSA5SStAKIOMcwaxas4bK5TKCP7nzzjuR1YMFKhhAJZCo2qKYMIkMk0hQgUBrwNoAwdhYCBvHsnSVSG0RrW3LKI0MQoCUsSxlWZayLEtb2NKEEI3nYYPAzJJGKWVaSQsajQZUKhX4zUe/QfPa5qGTJ08CXpJJdG9vAW4qRtDrW9DmAoQA4CNsbGwZxyLGd2zl25byHVsFriN9x5G+6wrf9YTneSJwPRF4vgh8XwS+LwPPU0HgKdfxtesF2nd843u+ieLItOfazZL5S8ymTZsMzMLJvwHA+wA9dd8sJLF2pWdsJ9DY97Tju8oLA+n5vgziiHthyP0wYn4UMtcPeRCGLA5DFoUxi4KQ5+KYx1Ek4lxO5OKcbCsU5JxiUXV1zVVd87r00oVLdU9PjwmCAP7o2LFjhry3d2N4+O57rHXXbrceXFN12r7ZdNY8IJwNZeVeyoxzRex2ptCAXdu5x2ruskn6nIWetmwQjqvBcRXxfGEHAQtzuSzOFdK2A6WkY25H0tXdnSy8ZnFy3fLl6e8G/yfp+0pftmHDBlq+WmYHDhzg99xzj5yamlLk0Z9sCcJ3P7YW5bZbz94urTm/Z/aND0rnzjo4f5va9rhy7Wnjkgb+J9zAe3HzuQFI93haOp4CJxA4iJgd5TK/WMj2zfnXpK2jM5nX29vqXXRta8Wfr2itX7eudfHzS+mWLVvSx7/7OH3hn19gfX19or+/X65evVpZA3/do89vvVHNt1dKtuoTma4SYskKwntO+WxOo0Bj08hcXHeQk1nIaWLldxk6l0tFhUW0QTYQ5bou87u6szn5Qlrq6Uk7FvRmi66/Plu+chW7Zc0tfNfePeL2zbfLPd/fo3bs2KFaqKURQnrFihXGemP9Tfr03YPq9xNfqN1fvUGOfh+LNZditvgvYtZZLdO8PZ15uGwTr0mM30Ki0TKMSoEYt4hQiBBL2a7L/TkhzRXb0tKSpen8xQuzJStW0r6vraUbH3iQbd26lX9y7hOx43s7JG1QFcexPn78uFm7dq0h8Vs/cb+9Zht56FSAH97yPH7hoX3kuvJu646nI3L3EzEZsfJ4nNl4yg3RlBPCd93I1N1QGz9SVhALLy6yuNROCws6s+6enuSalSuT6//shuTmvjXJ3Z/8Lnnq0UfS3c/tyfYO7KXLFy9nzWaT7927V7744oty06ZNmtzK1zul+/4R/3uvwVu3tuOd93vkmseeJxv4D8iG7+wn255rw2MU4yt2iCZIgL7j5syUH2vsx8rLFbmfL/GX2jtp+7Xzsnm916SLb1ydrl79leT2D7+e3L/l3nTgqX/Ifvyjn2Zv/OwN+tsLv+Wff/q5LJfLIgxDjTHWZN8f9ts3tp5HT/3gGXz6/g789GNz8DWPReSvdkTk1OUfki279uPhp3bii8jDV6wAHvYiMxHntRXmlBvlZVTsYP/S3sU6li3IehYuypavXZv+5dfeSU5//RvZ3//do+nCMMiOHv0PeuKXJ9iVkSvirv67xOGfH5aPP/i4unr1qv4/bGwpHb1ZNmYAAAAASUVORK5CYII="; /** * Sunglasses smiley From 1c048484808b63ad01160b51d666daf061e64ac4 Mon Sep 17 00:00:00 2001 From: John L Date: Wed, 6 Apr 2022 10:51:52 +0100 Subject: [PATCH 031/111] added log_path --- nightwatch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nightwatch.json b/nightwatch.json index 072e6c52..5b33631b 100644 --- a/nightwatch.json +++ b/nightwatch.json @@ -10,7 +10,7 @@ "start_process": true, "server_path": "./node_modules/.bin/chromedriver", "port": 9515, - "log_path": false + "log_path": "tests/browser/output" }, "desiredCapabilities": { "browserName": "chrome" From c431fb30c5a8225c1fc6a63adfc40350a4d3a5d6 Mon Sep 17 00:00:00 2001 From: John L Date: Wed, 6 Apr 2022 10:54:20 +0100 Subject: [PATCH 032/111] added logging & jsdoc --- tests/browser/ops.js | 65 ++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/tests/browser/ops.js b/tests/browser/ops.js index 09740cc8..34fd6a5b 100644 --- a/tests/browser/ops.js +++ b/tests/browser/ops.js @@ -198,8 +198,9 @@ module.exports = { // testOp(browser, "MD4", "test input", "test_output"); // testOp(browser, "MD5", "test input", "test_output"); // testOp(browser, "MD6", "test input", "test_output"); - // testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "td", /Result snippet/); - testOpHtml(browser, "Magic", "dGVzdCBvdXRwdXQ=", "tr:{1} td:{2}", "Result snippet"); + testOpHtml(browser, "Magic", "dGVzdF9vdXRwdXQ=", "tr:nth-of-type(1) th:nth-of-type(2)", "Result snippet"); + testOpHtml(browser, "Magic", "dGVzdF9vdXRwdXQ=", "tr:nth-of-type(2) td:nth-of-type(2)", "test_output"); + testOpHtml(browser, "Magic", "dGVzdF9vdXRwdXQ=", "tr:nth-of-type(2) td:nth-of-type(1)", /Base64/); // testOp(browser, "Mean", "test input", "test_output"); // testOp(browser, "Median", "test input", "test_output");` // testOp(browser, "Merge", "test input", "test_output");` @@ -374,26 +375,30 @@ module.exports = { } }; -/** +/** @function * Clears the current recipe and bakes a new operation. * - * @param {string} opName - * @param {Browser} browser + * @param {Browser} browser - Nightwatch client + * @param {string|Array} opName - name of operation to be tested, array for pre & post ops + * @param {string} input - input text for test + * @param {Array.} args - arguments for test */ function bakeOp(browser, opName, input, args=[]) { - let recipeConfig; + let op, recipeConfig; /* * Create recipeConfig as single operation * or wrapped with a pre-op and * possibly a post-op too */ if (typeof(opName) === "string") { + op = opName; recipeConfig = JSON.stringify([{ "op": opName, "args": args }]); } else if (opName.length === 2) { + op = opName[1]; recipeConfig = JSON.stringify([{ "op": opName[0], "args": [] @@ -402,6 +407,7 @@ function bakeOp(browser, opName, input, args=[]) { "args": args }]); } else { + op = opName[1]; recipeConfig = JSON.stringify([{ "op": opName[0], "args": [] @@ -411,7 +417,6 @@ function bakeOp(browser, opName, input, args=[]) { }, { "op": opName[2], "args": [] - }]); } @@ -419,18 +424,22 @@ function bakeOp(browser, opName, input, args=[]) { .useCss() .click("#clr-recipe") .click("#clr-io") + .perform(function() { + console.log("\nCurrent Operation: ", op); + }) .waitForElementNotPresent("#rec-list li.operation") .expect.element("#input-text").to.have.property("value").that.equals(""); + let currentUrl; browser .urlHash("recipe=" + recipeConfig) + // get the current URL .url(function(result) { currentUrl = result; }) + // and put it out .perform(function() { - console.log(currentUrl); - console.log(opName); - console.log(recipeConfig); + console.log("Current URL: ", currentUrl.value); }) .setValue("#input-text", input) .waitForElementPresent("#rec-list li.operation") @@ -443,22 +452,16 @@ function bakeOp(browser, opName, input, args=[]) { .pause(100) .waitForElementPresent("#stale-indicator.hidden", 5000) .waitForElementNotVisible("#output-loader", 5000); - - let currentUrl=""; - browser - .url(function(result) { - currentUrl = result; - }) - .perform(function() { - console.log(currentUrl.value); - }); } -/** +/** @function * Clears the current recipe and tests a new operation. * - * @param {string} opName - * @param {Browser} browser + * @param {Browser} browser - Nightwatch client + * @param {string|Array} opName - name of operation to be tested, array for pre & post ops + * @param {string} input - input text for test + * @param {string} output - expected output + * @param {Array.} args - arguments for test */ function testOp(browser, opName, input, output, args=[]) { @@ -471,19 +474,23 @@ function testOp(browser, opName, input, output, args=[]) { } } -/** +/** @function * Clears the current recipe and tests a new operation. * - * @param {string} opName - * @param {Browser} browser + * @param {Browser} browser - Nightwatch client + * @param {string} opName - name of operation to be tested + * @param {string} input - input text for test + * @param {string} cssSelector - CSS selector for HTML output + * @param {string} output - expected output + * @param {Array.} args - arguments for test */ -function testOpHtml(browser, opName, input, element, output, args=[]) { +function testOpHtml(browser, opName, input, cssSelector, output, args=[]) { bakeOp(browser, opName, input, args); - browser.waitForElementPresent("#output-html", 5000); + if (typeof output === "string") { - browser.expect.element("#output-html " + element).to.have.value.that.equals(output); + browser.expect.element("#output-html " + cssSelector).text.that.equals(output); } else if (output instanceof RegExp) { - browser.expect.element("#output-html " + element).to.have.value.that.matches(output); + browser.expect.element("#output-html " + cssSelector).text.that.matches(output); } } From e712af33b78764fceb90f40a17ffb800f13fcd38 Mon Sep 17 00:00:00 2001 From: Thomas Leplus Date: Mon, 11 Apr 2022 18:44:14 -0700 Subject: [PATCH 033/111] Adding ROT8000 --- src/core/config/Categories.json | 4 +- src/core/operations/ROT8000.mjs | 105 ++++++++++++++++++++++++++++++ tests/browser/ops.js | 1 + tests/operations/tests/Rotate.mjs | 33 ++++++++++ 4 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 src/core/operations/ROT8000.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 9540f8a3..f9e47aac 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -87,6 +87,7 @@ "SM4 Decrypt", "ROT13", "ROT47", + "ROT8000", "XOR", "XOR Brute Force", "Vigenère Encode", @@ -176,7 +177,8 @@ "Bit shift right", "Rotate left", "Rotate right", - "ROT13" + "ROT13", + "ROT8000" ] }, { diff --git a/src/core/operations/ROT8000.mjs b/src/core/operations/ROT8000.mjs new file mode 100644 index 00000000..1f039de0 --- /dev/null +++ b/src/core/operations/ROT8000.mjs @@ -0,0 +1,105 @@ +/** + * @author Daniel Temkin [http://danieltemkin.com] + * @author Thomas Leplus [https://www.leplus.org] + * @copyright Crown Copyright 2021 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; + +/** + * ROT8000 operation. + */ +class ROT8000 extends Operation { + + /** + * ROT8000 constructor + */ + constructor() { + super(); + this.name = "ROT8000"; + this.module = "Default"; + this.description = "The simple Caesar-cypher encryption that replaces each Unicode character with the one 0x8000 places forward or back along the alphabet."; + this.infoURL = "https://github.com/rottytooth/rot8000"; + this.inputType = "string"; + this.outputType = "string"; + this.args = []; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + // Inspired from https://github.com/rottytooth/rot8000/blob/main/rot8000.js + // these come from the valid-code-point-transitions.json file generated from the c# proj + // this is done bc: 1) don't trust JS's understanging of surrogate pairs and 2) consistency with original rot8000 + const validCodePoints = JSON.parse('{"33":true,"127":false,"161":true,"5760":false,"5761":true,"8192":false,"8203":true,"8232":false,"8234":true,"8239":false,"8240":true,"8287":false,"8288":true,"12288":false,"12289":true,"55296":false,"57344":true}'); + const bmpSize = 0x10000; + const rotList = {}; // the mapping of char to rotated char + const hiddenBlocks = []; + let startBlock = 0; + for (const key in validCodePoints) { + if (Object.prototype.hasOwnProperty.call(validCodePoints, key)) { + if (validCodePoints[key] === true) + hiddenBlocks.push({ start: startBlock, end: parseInt(key, 10) - 1 }); + else + startBlock = parseInt(key, 10); + } + } + const validIntList = []; // list of all valid chars + let currValid = false; + for (let i = 0; i < bmpSize; i++) { + if (validCodePoints[i] !== undefined) { + currValid = validCodePoints[i]; + } + if (currValid) validIntList.push(i); + } + const rotateNum = Object.keys(validIntList).length / 2; + // go through every valid char and find its match + for (let i = 0; i < validIntList.length; i++) { + rotList[String.fromCharCode(validIntList[i])] = + String.fromCharCode(validIntList[(i + rotateNum) % (rotateNum * 2)]); + } + let output = ""; + for (let count = 0; count < input.length; count++) { + // if it is not in the mappings list, just add it directly (no rotation) + if (rotList[input[count]] === undefined) { + output += input[count]; + continue; + } + // otherwise, rotate it and add it to the string + output += rotList[input[count]]; + } + return output; + } + + /** + * Highlight ROT8000 + * + * @param {Object[]} pos + * @param {number} pos[].start + * @param {number} pos[].end + * @param {Object[]} args + * @returns {Object[]} pos + */ + highlight(pos, args) { + return pos; + } + + /** + * Highlight ROT8000 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 ROT8000; diff --git a/tests/browser/ops.js b/tests/browser/ops.js index f2522a79..62436a89 100644 --- a/tests/browser/ops.js +++ b/tests/browser/ops.js @@ -246,6 +246,7 @@ module.exports = { // testOp(browser, "RIPEMD", "test input", "test_output"); // testOp(browser, "ROT13", "test input", "test_output"); // testOp(browser, "ROT47", "test input", "test_output"); + // testOp(browser, "ROT8000", "test input", "test_output"); // testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output"); // testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output"); // testOp(browser, "Randomize Colour Palette", "test input", "test_output"); diff --git a/tests/operations/tests/Rotate.mjs b/tests/operations/tests/Rotate.mjs index 85e31508..c12fa377 100644 --- a/tests/operations/tests/Rotate.mjs +++ b/tests/operations/tests/Rotate.mjs @@ -212,4 +212,37 @@ TestRegister.addTests([ }, ], }, + { + name: "ROT8000: nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "ROT8000", + args: [] + }, + ], + }, + { + name: "ROT8000: normal", + input: "The Quick Brown Fox Jumped Over The Lazy Dog.", + expectedOutput: "籝籱籮 籚籾籲籬籴 籋类籸粀籷 籏籸粁 籓籾籶籹籮籭 籘籿籮类 籝籱籮 籕籪粃粂 籍籸籰簷", + recipeConfig: [ + { + op: "ROT8000", + args: [] + }, + ], + }, + { + name: "ROT8000: backward", + input: "籝籱籮 籚籾籲籬籴 籋类籸粀籷 籏籸粁 籓籾籶籹籮籭 籘籿籮类 籝籱籮 籕籪粃粂 籍籸籰簷", + expectedOutput: "The Quick Brown Fox Jumped Over The Lazy Dog.", + recipeConfig: [ + { + op: "ROT8000", + args: [] + }, + ], + }, ]); From ccaabfaee8ddf618badc243cb088c27f52b97f71 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 11:55:34 +0100 Subject: [PATCH 034/111] Fixed incorrect wording for RC4 Drop argument. --- src/core/operations/RC4Drop.mjs | 4 ++-- tests/node/tests/operations.mjs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/operations/RC4Drop.mjs b/src/core/operations/RC4Drop.mjs index 3d87f4cb..c6bb536a 100644 --- a/src/core/operations/RC4Drop.mjs +++ b/src/core/operations/RC4Drop.mjs @@ -43,9 +43,9 @@ class RC4Drop extends Operation { "value": ["Latin1", "UTF8", "UTF16", "UTF16LE", "UTF16BE", "Hex", "Base64"] }, { - "name": "Number of bytes to drop", + "name": "Number of dwords to drop", "type": "number", - "value": 768 + "value": 192 } ]; } diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index 3f5631bd..305debfb 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -816,7 +816,7 @@ pCGTErs= it("RC4 Drop", () => { assert.strictEqual( chef.RC4Drop("Go Out On a Limb", {passphrase: {string: "Under Your Nose", option: "UTF8"}, inputFormat: "UTF8", outputFormat: "Hex"}).toString(), - "8fa5f2751d34476a0c857439f43816cf"); + "b85cb1c4ed6bed8f260ab92829bba942"); }), it("Regular Expression", () => { From fb3eceaee04ed11ca9e80aa0e2ecacf0ba4d3206 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 13:16:36 +0100 Subject: [PATCH 035/111] Tidied up UI tests --- nightwatch.json | 3 +- tests/browser/ops.js | 74 ++++++++++++++------------------------------ 2 files changed, 26 insertions(+), 51 deletions(-) diff --git a/nightwatch.json b/nightwatch.json index 5b33631b..21836547 100644 --- a/nightwatch.json +++ b/nightwatch.json @@ -14,7 +14,8 @@ }, "desiredCapabilities": { "browserName": "chrome" - } + }, + "enable_fail_fast": true }, "dev": { diff --git a/tests/browser/ops.js b/tests/browser/ops.js index 34fd6a5b..bb18dc5d 100644 --- a/tests/browser/ops.js +++ b/tests/browser/ops.js @@ -25,7 +25,7 @@ module.exports = { testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]); testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]); testOp(browser, "Add line numbers", "test input", "1 test input"); - testOp(browser, ["From Hex", "Add Text To Image", "To Base64"], Images.PNG_HEX, Images.PNG_CHEF_B64, ["Chef", "Center", "Middle", 0, 0, 16]); + testOp(browser, ["From Hex", "Add Text To Image", "To Base64"], Images.PNG_HEX, Images.PNG_CHEF_B64, [[], ["Chef", "Center", "Middle", 0, 0, 16], []]); testOp(browser, "Adler-32 Checksum", "test input", "16160411"); testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]); testOp(browser, "Affine Cipher Encode", "test input", "njln rbfpn", [2, 1]); @@ -49,8 +49,8 @@ module.exports = { testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]); testOp(browser, ["From Hex", "Blur Image", "To Base64"], Images.PNG_HEX, Images.PNG_BLUR_B64); // testOp(browser, "Bombe", "test input", "test_output"); - testOp(browser, "Bzip2 Compress", "test input", "BZh91AY&SYÏ........@..!N. .!.Â.À.3..ß.rE8P.Ï..."); - testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [true]); + testOp(browser, ["Bzip2 Compress", "To Hex"], "test input", "42 5a 68 39 31 41 59 26 53 59 cf 96 82 1d 00 00 03 91 80 40 00 02 21 4e 00 20 00 21 90 c2 10 c0 88 33 92 8e df 17 72 45 38 50 90 cf 96 82 1d"); + testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [[], [true]]); // testOp(browser, "CRC-16 Checksum", "test input", "test_output"); // testOp(browser, "CRC-32 Checksum", "test input", "test_output"); // testOp(browser, "CRC-8 Checksum", "test input", "test_output"); @@ -379,68 +379,43 @@ module.exports = { * Clears the current recipe and bakes a new operation. * * @param {Browser} browser - Nightwatch client - * @param {string|Array} opName - name of operation to be tested, array for pre & post ops + * @param {string|Array} opName - name of operation to be tested, array for multiple ops * @param {string} input - input text for test - * @param {Array.} args - arguments for test + * @param {Array|Array>} args - aarguments, nested if multiple ops */ function bakeOp(browser, opName, input, args=[]) { + let recipeConfig; - let op, recipeConfig; - /* - * Create recipeConfig as single operation - * or wrapped with a pre-op and - * possibly a post-op too - */ if (typeof(opName) === "string") { - op = opName; recipeConfig = JSON.stringify([{ "op": opName, "args": args }]); - } else if (opName.length === 2) { - op = opName[1]; - recipeConfig = JSON.stringify([{ - "op": opName[0], - "args": [] - }, { - "op": opName[1], - "args": args - }]); + } else if (opName instanceof Array) { + recipeConfig = JSON.stringify( + opName.map((op, i) => { + return { + op: op, + args: args.length ? args[i] : [] + }; + }) + ); } else { - op = opName[1]; - recipeConfig = JSON.stringify([{ - "op": opName[0], - "args": [] - }, { - "op": opName[1], - "args": args - }, { - "op": opName[2], - "args": [] - }]); + throw new Error("Invalid operation type. Must be string or array of strings. Received: " + typeof(opName)); } browser .useCss() .click("#clr-recipe") .click("#clr-io") - .perform(function() { - console.log("\nCurrent Operation: ", op); - }) .waitForElementNotPresent("#rec-list li.operation") .expect.element("#input-text").to.have.property("value").that.equals(""); - let currentUrl; browser - .urlHash("recipe=" + recipeConfig) - // get the current URL - .url(function(result) { - currentUrl = result; - }) - // and put it out .perform(function() { - console.log("Current URL: ", currentUrl.value); + console.log(`Current test: ${opName}`); }) + .urlHash("recipe=" + recipeConfig) .setValue("#input-text", input) .waitForElementPresent("#rec-list li.operation") .expect.element("#input-text").to.have.property("value").that.equals(input); @@ -458,10 +433,10 @@ function bakeOp(browser, opName, input, args=[]) { * Clears the current recipe and tests a new operation. * * @param {Browser} browser - Nightwatch client - * @param {string|Array} opName - name of operation to be tested, array for pre & post ops - * @param {string} input - input text for test + * @param {string|Array} opName - name of operation to be tested, array for multiple ops + * @param {string} input - input text * @param {string} output - expected output - * @param {Array.} args - arguments for test + * @param {Array|Array>} args - arguments, nested if multiple ops */ function testOp(browser, opName, input, output, args=[]) { @@ -478,14 +453,13 @@ function testOp(browser, opName, input, output, args=[]) { * Clears the current recipe and tests a new operation. * * @param {Browser} browser - Nightwatch client - * @param {string} opName - name of operation to be tested - * @param {string} input - input text for test + * @param {string|Array} opName - name of operation to be tested array for multiple ops + * @param {string} input - input text * @param {string} cssSelector - CSS selector for HTML output * @param {string} output - expected output - * @param {Array.} args - arguments for test + * @param {Array|Array>} args - arguments, nested if multiple ops */ function testOpHtml(browser, opName, input, cssSelector, output, args=[]) { - bakeOp(browser, opName, input, args); if (typeof output === "string") { From f77633cee95fdf2460de82acadfaa8605b0e604f Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 13:17:43 +0100 Subject: [PATCH 036/111] 9.37.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a0f0453b..36dcbd88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.37.0", + "version": "9.37.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.37.0", + "version": "9.37.1", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 02be5cbc..5f774478 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.37.0", + "version": "9.37.1", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From f5fe79326a92a16fd466aeadfb84a514c233ed4c Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 16:57:46 +0100 Subject: [PATCH 037/111] CodeQL fixes --- src/core/Utils.mjs | 4 ++-- src/core/operations/ToBase45.mjs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index c48c484c..66a98c36 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -723,8 +723,8 @@ class Utils { } if (removeScriptAndStyle) { - htmlStr = recursiveRemove(/]*>.*?<\/script>/gi, htmlStr); - htmlStr = recursiveRemove(/]*>.*?<\/style>/gi, htmlStr); + htmlStr = recursiveRemove(/]*>.*?<\/script[^>]*>/gi, htmlStr); + htmlStr = recursiveRemove(/]*>.*?<\/style[^>]*>/gi, htmlStr); } return htmlStr.replace(/<[^>]+>/g, ""); } diff --git a/src/core/operations/ToBase45.mjs b/src/core/operations/ToBase45.mjs index 40dd96de..3246ab4e 100644 --- a/src/core/operations/ToBase45.mjs +++ b/src/core/operations/ToBase45.mjs @@ -43,9 +43,9 @@ class ToBase45 extends Operation { * @returns {string} */ run(input, args) { + if (!input) return ""; input = new Uint8Array(input); const alphabet = Utils.expandAlphRange(args[0]); - if (!input) return ""; const res = []; From 6959e2cf01737ea2adc5ceb2d6435d4142cc0480 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 16:57:51 +0100 Subject: [PATCH 038/111] 9.37.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 36dcbd88..352c54e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.37.1", + "version": "9.37.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.37.1", + "version": "9.37.2", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 5f774478..45e732fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.37.1", + "version": "9.37.2", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 9a982f05ac7065a2253f8f2d963f6e636d79783a Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 18:08:16 +0100 Subject: [PATCH 039/111] Extract operations now offer built-in Sort and Unique options. Unique operation offers option to count occurances. Closes #1334. --- src/core/lib/Extract.mjs | 27 +++-- src/core/lib/Sort.mjs | 105 +++++++++++++++++ src/core/operations/ExtractDates.mjs | 8 +- src/core/operations/ExtractDomains.mjs | 34 +++++- src/core/operations/ExtractEmailAddresses.mjs | 34 +++++- src/core/operations/ExtractFilePaths.mjs | 52 ++++++--- src/core/operations/ExtractIPAddresses.mjs | 71 ++++++----- src/core/operations/ExtractMACAddresses.mjs | 34 +++++- src/core/operations/ExtractURLs.mjs | 33 +++++- src/core/operations/Sort.mjs | 110 +----------------- src/core/operations/Strings.mjs | 50 +++++--- src/core/operations/Unique.mjs | 30 ++++- tests/node/tests/operations.mjs | 7 +- .../tests/ExtractEmailAddresses.mjs | 8 +- 14 files changed, 397 insertions(+), 206 deletions(-) create mode 100644 src/core/lib/Sort.mjs diff --git a/src/core/lib/Extract.mjs b/src/core/lib/Extract.mjs index 8b9f957e..18fec28c 100644 --- a/src/core/lib/Extract.mjs +++ b/src/core/lib/Extract.mjs @@ -12,15 +12,15 @@ * * @param {string} input * @param {RegExp} searchRegex - * @param {RegExp} removeRegex - A regular expression defining results to remove from the + * @param {RegExp} [removeRegex=null] - A regular expression defining results to remove from the * final list - * @param {boolean} includeTotal - Whether or not to include the total number of results + * @param {Function} [sortBy=null] - The sorting comparison function to apply + * @param {boolean} [unique=false] - Whether to unique the results * @returns {string} */ -export function search (input, searchRegex, removeRegex, includeTotal) { - let output = "", - total = 0, - match; +export function search(input, searchRegex, removeRegex=null, sortBy=null, unique=false) { + let results = []; + let match; while ((match = searchRegex.exec(input))) { // Moves pointer when an empty string is matched (prevents infinite loop) @@ -30,14 +30,19 @@ export function search (input, searchRegex, removeRegex, includeTotal) { if (removeRegex && removeRegex.test(match[0])) continue; - total++; - output += match[0] + "\n"; + + results.push(match[0]); } - if (includeTotal) - output = "Total found: " + total + "\n\n" + output; + if (sortBy) { + results = results.sort(sortBy); + } - return output; + if (unique) { + results = results.unique(); + } + + return results; } diff --git a/src/core/lib/Sort.mjs b/src/core/lib/Sort.mjs new file mode 100644 index 00000000..46bbebd9 --- /dev/null +++ b/src/core/lib/Sort.mjs @@ -0,0 +1,105 @@ +/** + * Sorting functions + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + * + */ + +/** + * Comparison operation for sorting of strings ignoring case. + * + * @param {string} a + * @param {string} b + * @returns {number} + */ +export function caseInsensitiveSort(a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()); +} + + +/** + * Comparison operation for sorting of IPv4 addresses. + * + * @param {string} a + * @param {string} b + * @returns {number} + */ +export function ipSort(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 + * @param {string} a + * @param {string} b + * @returns {number} + */ +export function numericSort(a, b) { + const 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])) { + const ret = a_[i].localeCompare(b_[i]); // Compare strings + if (ret !== 0) return ret; + } + if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers + if (a_[i] - b_[i] !== 0) return a_[i] - b_[i]; + } + } + + return a.localeCompare(b); +} + +/** + * Comparison operation for sorting of hexadecimal values. + * + * @author Chris van Marle + * @param {string} a + * @param {string} b + * @returns {number} + */ +export function hexadecimalSort(a, b) { + let a_ = a.split(/([^\da-f]+)/i), + b_ = b.split(/([^\da-f]+)/i); + + a_ = a_.map(v => { + const t = parseInt(v, 16); + return isNaN(t) ? v : t; + }); + + b_ = b_.map(v => { + const t = parseInt(v, 16); + return isNaN(t) ? v : t; + }); + + 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])) { + const ret = a_[i].localeCompare(b_[i]); // Compare strings + if (ret !== 0) return ret; + } + if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers + if (a_[i] - b_[i] !== 0) return a_[i] - b_[i]; + } + } + + return a.localeCompare(b); +} diff --git a/src/core/operations/ExtractDates.mjs b/src/core/operations/ExtractDates.mjs index dfe93c88..74c177d3 100644 --- a/src/core/operations/ExtractDates.mjs +++ b/src/core/operations/ExtractDates.mjs @@ -44,7 +44,13 @@ class ExtractDates extends Operation { date3 = "(?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])[- /.](?:19|20)\\d\\d", // mm/dd/yyyy regex = new RegExp(date1 + "|" + date2 + "|" + date3, "ig"); - return search(input, regex, null, displayTotal); + const results = search(input, regex); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/ExtractDomains.mjs b/src/core/operations/ExtractDomains.mjs index ea9aa3af..c28efbb5 100644 --- a/src/core/operations/ExtractDomains.mjs +++ b/src/core/operations/ExtractDomains.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search, DOMAIN_REGEX } from "../lib/Extract.mjs"; +import { caseInsensitiveSort } from "../lib/Sort.mjs"; /** * Extract domains operation @@ -25,9 +26,19 @@ class ExtractDomains extends Operation { this.outputType = "string"; this.args = [ { - "name": "Display total", - "type": "boolean", - "value": true + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -38,8 +49,21 @@ class ExtractDomains extends Operation { * @returns {string} */ run(input, args) { - const displayTotal = args[0]; - return search(input, DOMAIN_REGEX, null, displayTotal); + const [displayTotal, sort, unique] = args; + + const results = search( + input, + DOMAIN_REGEX, + null, + sort ? caseInsensitiveSort : null, + unique + ); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/ExtractEmailAddresses.mjs b/src/core/operations/ExtractEmailAddresses.mjs index 43bf3b64..f50e1aaf 100644 --- a/src/core/operations/ExtractEmailAddresses.mjs +++ b/src/core/operations/ExtractEmailAddresses.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search } from "../lib/Extract.mjs"; +import { caseInsensitiveSort } from "../lib/Sort.mjs"; /** * Extract email addresses operation @@ -25,9 +26,19 @@ class ExtractEmailAddresses extends Operation { this.outputType = "string"; this.args = [ { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -38,10 +49,23 @@ class ExtractEmailAddresses extends Operation { * @returns {string} */ run(input, args) { - const displayTotal = args[0], + const [displayTotal, sort, unique] = args, // email regex from: https://www.regextester.com/98066 regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}\])/ig; - return search(input, regex, null, displayTotal); + + const results = search( + input, + regex, + null, + sort ? caseInsensitiveSort : null, + unique + ); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/ExtractFilePaths.mjs b/src/core/operations/ExtractFilePaths.mjs index 04d3f73e..5de76fe5 100644 --- a/src/core/operations/ExtractFilePaths.mjs +++ b/src/core/operations/ExtractFilePaths.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search } from "../lib/Extract.mjs"; +import { caseInsensitiveSort } from "../lib/Sort.mjs"; /** * Extract file paths operation @@ -25,19 +26,29 @@ class ExtractFilePaths extends Operation { this.outputType = "string"; this.args = [ { - "name": "Windows", - "type": "boolean", - "value": true + name: "Windows", + type: "boolean", + value: true }, { - "name": "UNIX", - "type": "boolean", - "value": true + name: "UNIX", + type: "boolean", + value: true }, { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -48,7 +59,7 @@ class ExtractFilePaths extends Operation { * @returns {string} */ run(input, args) { - const [includeWinPath, includeUnixPath, displayTotal] = args, + const [includeWinPath, includeUnixPath, displayTotal, sort, unique] = args, winDrive = "[A-Z]:\\\\", winName = "[A-Z\\d][A-Z\\d\\- '_\\(\\)~]{0,61}", winExt = "[A-Z\\d]{1,6}", @@ -65,12 +76,25 @@ class ExtractFilePaths extends Operation { filePaths = unixPath; } - if (filePaths) { - const regex = new RegExp(filePaths, "ig"); - return search(input, regex, null, displayTotal); - } else { + if (!filePaths) { return ""; } + + const regex = new RegExp(filePaths, "ig"); + const results = search( + input, + regex, + null, + sort ? caseInsensitiveSort : null, + unique + ); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } + } } diff --git a/src/core/operations/ExtractIPAddresses.mjs b/src/core/operations/ExtractIPAddresses.mjs index 8d36a783..95e0a50f 100644 --- a/src/core/operations/ExtractIPAddresses.mjs +++ b/src/core/operations/ExtractIPAddresses.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search } from "../lib/Extract.mjs"; +import { ipSort } from "../lib/Sort.mjs"; /** * Extract IP addresses operation @@ -25,24 +26,34 @@ class ExtractIPAddresses extends Operation { this.outputType = "string"; this.args = [ { - "name": "IPv4", - "type": "boolean", - "value": true + name: "IPv4", + type: "boolean", + value: true }, { - "name": "IPv6", - "type": "boolean", - "value": false + name: "IPv6", + type: "boolean", + value: false }, { - "name": "Remove local IPv4 addresses", - "type": "boolean", - "value": false + name: "Remove local IPv4 addresses", + type: "boolean", + value: false }, { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -53,7 +64,7 @@ class ExtractIPAddresses extends Operation { * @returns {string} */ run(input, args) { - const [includeIpv4, includeIpv6, removeLocal, displayTotal] = args, + const [includeIpv4, includeIpv6, removeLocal, displayTotal, sort, unique] = args, ipv4 = "(?:(?:\\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})?", ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})((([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})"; let ips = ""; @@ -66,23 +77,29 @@ class ExtractIPAddresses extends Operation { ips = ipv6; } - if (ips) { - const regex = new RegExp(ips, "ig"); + if (!ips) return ""; - if (removeLocal) { - const ten = "10\\..+", - oneninetwo = "192\\.168\\..+", - oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+", - onetwoseven = "127\\..+", - removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo + - "|" + oneseventwo + "|" + onetwoseven + ")"); + const regex = new RegExp(ips, "ig"); - return search(input, regex, removeRegex, displayTotal); - } else { - return search(input, regex, null, displayTotal); - } + const ten = "10\\..+", + oneninetwo = "192\\.168\\..+", + oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+", + onetwoseven = "127\\..+", + removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo + + "|" + oneseventwo + "|" + onetwoseven + ")"); + + const results = search( + input, + regex, + removeLocal ? removeRegex : null, + sort ? ipSort : null, + unique + ); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; } else { - return ""; + return results.join("\n"); } } diff --git a/src/core/operations/ExtractMACAddresses.mjs b/src/core/operations/ExtractMACAddresses.mjs index d75b1a69..1689d18f 100644 --- a/src/core/operations/ExtractMACAddresses.mjs +++ b/src/core/operations/ExtractMACAddresses.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search } from "../lib/Extract.mjs"; +import { hexadecimalSort } from "../lib/Sort.mjs"; /** * Extract MAC addresses operation @@ -25,9 +26,19 @@ class ExtractMACAddresses extends Operation { this.outputType = "string"; this.args = [ { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -38,10 +49,21 @@ class ExtractMACAddresses extends Operation { * @returns {string} */ run(input, args) { - const displayTotal = args[0], - regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig; + const [displayTotal, sort, unique] = args, + regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig, + results = search( + input, + regex, + null, + sort ? hexadecimalSort : null, + unique + ); - return search(input, regex, null, displayTotal); + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/ExtractURLs.mjs b/src/core/operations/ExtractURLs.mjs index a5b26515..32cdb3a7 100644 --- a/src/core/operations/ExtractURLs.mjs +++ b/src/core/operations/ExtractURLs.mjs @@ -6,6 +6,7 @@ import Operation from "../Operation.mjs"; import { search, URL_REGEX } from "../lib/Extract.mjs"; +import { caseInsensitiveSort } from "../lib/Sort.mjs"; /** * Extract URLs operation @@ -25,9 +26,19 @@ class ExtractURLs extends Operation { this.outputType = "string"; this.args = [ { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -38,8 +49,20 @@ class ExtractURLs extends Operation { * @returns {string} */ run(input, args) { - const displayTotal = args[0]; - return search(input, URL_REGEX, null, displayTotal); + const [displayTotal, sort, unique] = args; + const results = search( + input, + URL_REGEX, + null, + sort ? caseInsensitiveSort : null, + unique + ); + + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/Sort.mjs b/src/core/operations/Sort.mjs index a1148f7c..19e4cbb2 100644 --- a/src/core/operations/Sort.mjs +++ b/src/core/operations/Sort.mjs @@ -7,6 +7,7 @@ import Operation from "../Operation.mjs"; import Utils from "../Utils.mjs"; import {INPUT_DELIM_OPTIONS} from "../lib/Delim.mjs"; +import {caseInsensitiveSort, ipSort, numericSort, hexadecimalSort} from "../lib/Sort.mjs"; /** * Sort operation @@ -57,120 +58,19 @@ class Sort extends Operation { if (order === "Alphabetical (case sensitive)") { sorted = sorted.sort(); } else if (order === "Alphabetical (case insensitive)") { - sorted = sorted.sort(Sort._caseInsensitiveSort); + sorted = sorted.sort(caseInsensitiveSort); } else if (order === "IP address") { - sorted = sorted.sort(Sort._ipSort); + sorted = sorted.sort(ipSort); } else if (order === "Numeric") { - sorted = sorted.sort(Sort._numericSort); + sorted = sorted.sort(numericSort); } else if (order === "Numeric (hexadecimal)") { - sorted = sorted.sort(Sort._hexadecimalSort); + sorted = sorted.sort(hexadecimalSort); } if (sortReverse) sorted.reverse(); return sorted.join(delim); } - /** - * Comparison operation for sorting of strings ignoring case. - * - * @private - * @param {string} a - * @param {string} b - * @returns {number} - */ - static _caseInsensitiveSort(a, b) { - return a.toLowerCase().localeCompare(b.toLowerCase()); - } - - - /** - * Comparison operation for sorting of IPv4 addresses. - * - * @private - * @param {string} a - * @param {string} b - * @returns {number} - */ - static _ipSort(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} - */ - static _numericSort(a, b) { - const 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])) { - const ret = a_[i].localeCompare(b_[i]); // Compare strings - if (ret !== 0) return ret; - } - if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers - if (a_[i] - b_[i] !== 0) return a_[i] - b_[i]; - } - } - - return a.localeCompare(b); - } - - /** - * Comparison operation for sorting of hexadecimal values. - * - * @author Chris van Marle - * @private - * @param {string} a - * @param {string} b - * @returns {number} - */ - static _hexadecimalSort(a, b) { - let a_ = a.split(/([^\da-f]+)/i), - b_ = b.split(/([^\da-f]+)/i); - - a_ = a_.map(v => { - const t = parseInt(v, 16); - return isNaN(t) ? v : t; - }); - - b_ = b_.map(v => { - const t = parseInt(v, 16); - return isNaN(t) ? v : t; - }); - - 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])) { - const ret = a_[i].localeCompare(b_[i]); // Compare strings - if (ret !== 0) return ret; - } - if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers - if (a_[i] - b_[i] !== 0) return a_[i] - b_[i]; - } - } - - return a.localeCompare(b); - } - } export default Sort; diff --git a/src/core/operations/Strings.mjs b/src/core/operations/Strings.mjs index ddf1d49d..dca2433a 100644 --- a/src/core/operations/Strings.mjs +++ b/src/core/operations/Strings.mjs @@ -7,6 +7,7 @@ import Operation from "../Operation.mjs"; import XRegExp from "xregexp"; import { search } from "../lib/Extract.mjs"; +import { caseInsensitiveSort } from "../lib/Sort.mjs"; /** * Strings operation @@ -27,27 +28,37 @@ class Strings extends Operation { this.outputType = "string"; this.args = [ { - "name": "Encoding", - "type": "option", - "value": ["Single byte", "16-bit littleendian", "16-bit bigendian", "All"] + name: "Encoding", + type: "option", + value: ["Single byte", "16-bit littleendian", "16-bit bigendian", "All"] }, { - "name": "Minimum length", - "type": "number", - "value": 4 + name: "Minimum length", + type: "number", + value: 4 }, { - "name": "Match", - "type": "option", - "value": [ + name: "Match", + type: "option", + value: [ "[ASCII]", "Alphanumeric + punctuation (A)", "All printable chars (A)", "Null-terminated strings (A)", "[Unicode]", "Alphanumeric + punctuation (U)", "All printable chars (U)", "Null-terminated strings (U)" ] }, { - "name": "Display total", - "type": "boolean", - "value": false + name: "Display total", + type: "boolean", + value: false + }, + { + name: "Sort", + type: "boolean", + value: false + }, + { + name: "Unique", + type: "boolean", + value: false } ]; } @@ -58,7 +69,7 @@ class Strings extends Operation { * @returns {string} */ run(input, args) { - const [encoding, minLen, matchType, displayTotal] = args, + const [encoding, minLen, matchType, displayTotal, sort, unique] = args, alphanumeric = "A-Z\\d", punctuation = "/\\-:.,_$%'\"()<>= !\\[\\]{}@", printable = "\x20-\x7e", @@ -108,8 +119,19 @@ class Strings extends Operation { } const regex = new XRegExp(strings, "ig"); + const results = search( + input, + regex, + null, + sort ? caseInsensitiveSort : null, + unique + ); - return search(input, regex, null, displayTotal); + if (displayTotal) { + return `Total found: ${results.length}\n\n${results.join("\n")}`; + } else { + return results.join("\n"); + } } } diff --git a/src/core/operations/Unique.mjs b/src/core/operations/Unique.mjs index 89de74c2..7ca2db66 100644 --- a/src/core/operations/Unique.mjs +++ b/src/core/operations/Unique.mjs @@ -26,9 +26,14 @@ class Unique extends Operation { this.outputType = "string"; this.args = [ { - "name": "Delimiter", - "type": "option", - "value": INPUT_DELIM_OPTIONS + name: "Delimiter", + type: "option", + value: INPUT_DELIM_OPTIONS + }, + { + name: "Display count", + type: "boolean", + value: false } ]; } @@ -39,8 +44,23 @@ class Unique extends Operation { * @returns {string} */ run(input, args) { - const delim = Utils.charRep(args[0]); - return input.split(delim).unique().join(delim); + const delim = Utils.charRep(args[0]), + count = args[1]; + + if (count) { + const valMap = input.split(delim).reduce((acc, curr) => { + if (Object.prototype.hasOwnProperty.call(acc, curr)) { + acc[curr]++; + } else { + acc[curr] = 1; + } + return acc; + }, {}); + + return Object.keys(valMap).map(val => `${valMap[val]} ${val}`).join(delim); + } else { + return input.split(delim).unique().join(delim); + } } } diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index 305debfb..783bd00a 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -471,7 +471,7 @@ color: white; }), it("Extract dates", () => { - assert.strictEqual(chef.extractDates("Don't Look a Gift Horse In The Mouth 01/02/1992").toString(), "01/02/1992\n"); + assert.strictEqual(chef.extractDates("Don't Look a Gift Horse In The Mouth 01/02/1992").toString(), "01/02/1992"); }), it("Filter", () => { @@ -859,7 +859,7 @@ pCGTErs= }), it("SQL Beautify", () => { - const result = chef.SQLBeautify(`SELECT MONTH, ID, RAIN_I, TEMP_F + const result = chef.SQLBeautify(`SELECT MONTH, ID, RAIN_I, TEMP_F FROM STATS;`); const expected = `SELECT MONTH, ID, @@ -879,8 +879,7 @@ FROM STATS;`; const result = chef.strings("smothering ampersand abreast", {displayTotal: true}); const expected = `Total found: 1 -smothering ampersand abreast -`; +smothering ampersand abreast`; assert.strictEqual(result.toString(), expected); }), diff --git a/tests/operations/tests/ExtractEmailAddresses.mjs b/tests/operations/tests/ExtractEmailAddresses.mjs index a0a01f67..658484cf 100644 --- a/tests/operations/tests/ExtractEmailAddresses.mjs +++ b/tests/operations/tests/ExtractEmailAddresses.mjs @@ -11,7 +11,7 @@ TestRegister.addTests([ { name: "Extract email address", input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com", - expectedOutput: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com\n", + expectedOutput: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com", recipeConfig: [ { "op": "Extract email addresses", @@ -22,7 +22,7 @@ TestRegister.addTests([ { name: "Extract email address - Display total", input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com", - expectedOutput: "Total found: 11\n\nemail@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com\n", + expectedOutput: "Total found: 11\n\nemail@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com", recipeConfig: [ { "op": "Extract email addresses", @@ -33,7 +33,7 @@ TestRegister.addTests([ { name: "Extract email address (Internationalized)", input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com", - expectedOutput: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com\n", + expectedOutput: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com", recipeConfig: [ { "op": "Extract email addresses", @@ -44,7 +44,7 @@ TestRegister.addTests([ { name: "Extract email address - Display total (Internationalized)", input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com", - expectedOutput: "Total found: 19\n\n\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com\n", + expectedOutput: "Total found: 19\n\n\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com", recipeConfig: [ { "op": "Extract email addresses", From 477e4a7421756c461293a8f0714fb75ee3ac1736 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 14 Apr 2022 18:08:23 +0100 Subject: [PATCH 040/111] 9.37.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 352c54e1..d956ea2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.37.2", + "version": "9.37.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.37.2", + "version": "9.37.3", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 45e732fb..73d2d19a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.37.2", + "version": "9.37.3", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From 5b68bad18568450cbbd2d42d40799e62185c2cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luke=20Sern=C3=A9?= Date: Fri, 13 May 2022 17:35:50 +0200 Subject: [PATCH 041/111] Support UTF8 encoded characters in Substitution operation This adds support for UTF8-encoded characters in the input and the parameters. --- src/core/operations/Substitute.mjs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/operations/Substitute.mjs b/src/core/operations/Substitute.mjs index 39f13e89..1afe1f42 100644 --- a/src/core/operations/Substitute.mjs +++ b/src/core/operations/Substitute.mjs @@ -44,8 +44,8 @@ class Substitute extends Operation { * @returns {string} */ run(input, args) { - const plaintext = Utils.expandAlphRange(args[0]).join(""), - ciphertext = Utils.expandAlphRange(args[1]).join(""); + const plaintext = Utils.expandAlphRange([...args[0]]), + ciphertext = Utils.expandAlphRange([...args[1]]); let output = "", index = -1; @@ -53,9 +53,9 @@ class Substitute extends Operation { output = "Warning: Plaintext and Ciphertext lengths differ\n\n"; } - for (let i = 0; i < input.length; i++) { - index = plaintext.indexOf(input[i]); - output += index > -1 && index < ciphertext.length ? ciphertext[index] : input[i]; + for (const character of input) { + index = plaintext.indexOf(character); + output += index > -1 && index < ciphertext.length ? ciphertext[index] : character; } return output; From 11da4188ee7d96df6ca96726f0d6321137294f94 Mon Sep 17 00:00:00 2001 From: MikeCAT Date: Fri, 20 May 2022 11:59:04 +0000 Subject: [PATCH 042/111] fix "To Base45" ( #1351 ) --- src/core/operations/ToBase45.mjs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/operations/ToBase45.mjs b/src/core/operations/ToBase45.mjs index 3246ab4e..a1cd9d2f 100644 --- a/src/core/operations/ToBase45.mjs +++ b/src/core/operations/ToBase45.mjs @@ -65,6 +65,10 @@ class ToBase45 extends Operation { if (chars < 2) { res.push("0"); + chars++; + } + if (pair.length > 1 && chars < 3) { + res.push("0"); } } From a895d1d82a2f92d440a0c5eca2bc7c898107b737 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 30 May 2022 18:06:15 +0100 Subject: [PATCH 043/111] Added 'Parse TCP' operation --- Gruntfile.js | 3 +- package-lock.json | 14 +- package.json | 2 +- src/core/config/Categories.json | 1 + src/core/lib/Binary.mjs | 14 +- src/core/lib/FileSignatures.mjs | 24 +-- src/core/lib/Protocol.mjs | 47 +++++ src/core/lib/Stream.mjs | 34 ++-- src/core/operations/ParseTCP.mjs | 245 +++++++++++++++++++++++++++ src/core/operations/ParseUDP.mjs | 53 +++--- src/web/waiters/OperationsWaiter.mjs | 6 +- tests/operations/index.mjs | 1 + tests/operations/tests/ParseTCP.mjs | 44 +++++ tests/operations/tests/ParseUDP.mjs | 23 +-- 14 files changed, 430 insertions(+), 81 deletions(-) create mode 100644 src/core/lib/Protocol.mjs create mode 100644 src/core/operations/ParseTCP.mjs create mode 100644 tests/operations/tests/ParseTCP.mjs diff --git a/Gruntfile.js b/Gruntfile.js index f073a136..78c26532 100755 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -217,7 +217,8 @@ module.exports = function (grunt) { client: { logging: "error", overlay: true - } + }, + hot: "only" }, plugins: [ new webpack.DefinePlugin(BUILD_CONSTANTS), diff --git a/package-lock.json b/package-lock.json index d956ea2f..16c88c1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -98,7 +98,7 @@ "autoprefixer": "^10.4.4", "babel-loader": "^8.2.4", "babel-plugin-dynamic-import-node": "^2.3.3", - "chromedriver": "^99.0.0", + "chromedriver": "^101.0.0", "cli-progress": "^3.10.0", "colors": "^1.4.0", "copy-webpack-plugin": "^10.2.4", @@ -4467,9 +4467,9 @@ } }, "node_modules/chromedriver": { - "version": "99.0.0", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-99.0.0.tgz", - "integrity": "sha512-pyB+5LuyZdb7EBPL3i5D5yucZUD+SlkdiUtmpjaEnLd9zAXp+SvD/hP5xF4l/ZmWvUo/1ZLxAI1YBdhazGTpgA==", + "version": "101.0.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-101.0.0.tgz", + "integrity": "sha512-LkkWxy6KM/0YdJS8qBeg5vfkTZTRamhBfOttb4oic4echDgWvCU1E8QcBbUBOHqZpSrYMyi7WMKmKMhXFUaZ+w==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -19171,9 +19171,9 @@ "dev": true }, "chromedriver": { - "version": "99.0.0", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-99.0.0.tgz", - "integrity": "sha512-pyB+5LuyZdb7EBPL3i5D5yucZUD+SlkdiUtmpjaEnLd9zAXp+SvD/hP5xF4l/ZmWvUo/1ZLxAI1YBdhazGTpgA==", + "version": "101.0.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-101.0.0.tgz", + "integrity": "sha512-LkkWxy6KM/0YdJS8qBeg5vfkTZTRamhBfOttb4oic4echDgWvCU1E8QcBbUBOHqZpSrYMyi7WMKmKMhXFUaZ+w==", "dev": true, "requires": { "@testim/chrome-version": "^1.1.2", diff --git a/package.json b/package.json index 73d2d19a..d2d71272 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "autoprefixer": "^10.4.4", "babel-loader": "^8.2.4", "babel-plugin-dynamic-import-node": "^2.3.3", - "chromedriver": "^99.0.0", + "chromedriver": "^101.0.0", "cli-progress": "^3.10.0", "colors": "^1.4.0", "copy-webpack-plugin": "^10.2.4", diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index 9540f8a3..c15ec3d2 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -190,6 +190,7 @@ "Parse IP range", "Parse IPv6 address", "Parse IPv4 header", + "Parse TCP", "Parse UDP", "Parse SSH Host Key", "Parse URI", diff --git a/src/core/lib/Binary.mjs b/src/core/lib/Binary.mjs index dc63fc58..4e41d2a1 100644 --- a/src/core/lib/Binary.mjs +++ b/src/core/lib/Binary.mjs @@ -13,7 +13,7 @@ import OperationError from "../errors/OperationError.mjs"; /** * Convert a byte array into a binary string. * - * @param {Uint8Array|byteArray} data + * @param {Uint8Array|byteArray|number} data * @param {string} [delim="Space"] * @param {number} [padding=8] * @returns {string} @@ -26,13 +26,17 @@ import OperationError from "../errors/OperationError.mjs"; * toBinary([10,20,30], ":"); */ export function toBinary(data, delim="Space", padding=8) { - if (!data) return ""; - delim = Utils.charRep(delim); let output = ""; - for (let i = 0; i < data.length; i++) { - output += data[i].toString(2).padStart(padding, "0") + delim; + if (data.length) { // array + for (let i = 0; i < data.length; i++) { + output += data[i].toString(2).padStart(padding, "0") + delim; + } + } else if (typeof data === "number") { // Single value + return data.toString(2).padStart(padding, "0"); + } else { + return ""; } if (delim.length) { diff --git a/src/core/lib/FileSignatures.mjs b/src/core/lib/FileSignatures.mjs index a515a9e6..7b77f2d9 100644 --- a/src/core/lib/FileSignatures.mjs +++ b/src/core/lib/FileSignatures.mjs @@ -3778,8 +3778,8 @@ function parseDEFLATE(stream) { while (!finalBlock) { // Read header - finalBlock = stream.readBits(1); - const blockType = stream.readBits(2); + finalBlock = stream.readBits(1, "le"); + const blockType = stream.readBits(2, "le"); if (blockType === 0) { /* No compression */ @@ -3798,16 +3798,16 @@ function parseDEFLATE(stream) { /* Dynamic Huffman */ // Read the number of liternal and length codes - const hlit = stream.readBits(5) + 257; + const hlit = stream.readBits(5, "le") + 257; // Read the number of distance codes - const hdist = stream.readBits(5) + 1; + const hdist = stream.readBits(5, "le") + 1; // Read the number of code lengths - const hclen = stream.readBits(4) + 4; + const hclen = stream.readBits(4, "le") + 4; // Parse code lengths const codeLengths = new Uint8Array(huffmanOrder.length); for (let i = 0; i < hclen; i++) { - codeLengths[huffmanOrder[i]] = stream.readBits(3); + codeLengths[huffmanOrder[i]] = stream.readBits(3, "le"); } // Parse length table @@ -3819,16 +3819,16 @@ function parseDEFLATE(stream) { code = readHuffmanCode(stream, codeLengthsTable); switch (code) { case 16: - repeat = 3 + stream.readBits(2); + repeat = 3 + stream.readBits(2, "le"); while (repeat--) lengthTable[i++] = prev; break; case 17: - repeat = 3 + stream.readBits(3); + repeat = 3 + stream.readBits(3, "le"); while (repeat--) lengthTable[i++] = 0; prev = 0; break; case 18: - repeat = 11 + stream.readBits(7); + repeat = 11 + stream.readBits(7, "le"); while (repeat--) lengthTable[i++] = 0; prev = 0; break; @@ -3886,11 +3886,11 @@ function parseHuffmanBlock(stream, litTab, distTab) { if (code < 256) continue; // Length code - stream.readBits(lengthExtraTable[code - 257]); + stream.readBits(lengthExtraTable[code - 257], "le"); // Dist code code = readHuffmanCode(stream, distTab); - stream.readBits(distanceExtraTable[code]); + stream.readBits(distanceExtraTable[code], "le"); } } @@ -3948,7 +3948,7 @@ function readHuffmanCode(stream, table) { const [codeTable, maxCodeLength] = table; // Read max length - const bitsBuf = stream.readBits(maxCodeLength); + const bitsBuf = stream.readBits(maxCodeLength, "le"); const codeWithLength = codeTable[bitsBuf & ((1 << maxCodeLength) - 1)]; const codeLength = codeWithLength >>> 16; diff --git a/src/core/lib/Protocol.mjs b/src/core/lib/Protocol.mjs new file mode 100644 index 00000000..57d2374a --- /dev/null +++ b/src/core/lib/Protocol.mjs @@ -0,0 +1,47 @@ +/** + * Protocol parsing functions. + * + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import BigNumber from "bignumber.js"; +import {toHexFast} from "../lib/Hex.mjs"; + +/** + * Recursively displays a JSON object as an HTML table + * + * @param {Object} obj + * @returns string + */ +export function objToTable(obj, nested=false) { + let html = ``; + if (!nested) + html += ` + + + `; + + for (const key in obj) { + html += ``; + if (typeof obj[key] === "object") + html += ``; + else + html += ``; + html += ""; + } + html += "
FieldValue
${key}${objToTable(obj[key], true)}${obj[key]}
"; + return html; +} + +/** + * Converts bytes into a BigNumber string + * @param {Uint8Array} bs + * @returns {string} + */ +export function bytesToLargeNumber(bs) { + return BigNumber(toHexFast(bs), 16).toString(); +} diff --git a/src/core/lib/Stream.mjs b/src/core/lib/Stream.mjs index f332f908..b2a183f4 100644 --- a/src/core/lib/Stream.mjs +++ b/src/core/lib/Stream.mjs @@ -27,15 +27,17 @@ export default class Stream { } /** - * Get a number of bytes from the current position. + * Get a number of bytes from the current position, or all remaining bytes. * - * @param {number} numBytes + * @param {number} [numBytes=null] * @returns {Uint8Array} */ - getBytes(numBytes) { + getBytes(numBytes=null) { if (this.position > this.length) return undefined; - const newPosition = this.position + numBytes; + const newPosition = numBytes !== null ? + this.position + numBytes : + this.length; const bytes = this.bytes.slice(this.position, newPosition); this.position = newPosition; this.bitPos = 0; @@ -91,34 +93,40 @@ export default class Stream { } /** - * Reads a number of bits from the buffer. - * - * @TODO Add endianness + * Reads a number of bits from the buffer in big or little endian. * * @param {number} numBits + * @param {string} [endianness="be"] * @returns {number} */ - readBits(numBits) { + readBits(numBits, endianness="be") { if (this.position > this.length) return undefined; let bitBuf = 0, bitBufLen = 0; // Add remaining bits from current byte - bitBuf = (this.bytes[this.position++] & bitMask(this.bitPos)) >>> this.bitPos; + bitBuf = this.bytes[this.position++] & bitMask(this.bitPos); + if (endianness !== "be") bitBuf >>>= this.bitPos; bitBufLen = 8 - this.bitPos; this.bitPos = 0; // Not enough bits yet while (bitBufLen < numBits) { - bitBuf |= this.bytes[this.position++] << bitBufLen; + if (endianness === "be") + bitBuf = (bitBuf << bitBufLen) | this.bytes[this.position++]; + else + bitBuf |= this.bytes[this.position++] << bitBufLen; bitBufLen += 8; } // Reverse back to numBits if (bitBufLen > numBits) { const excess = bitBufLen - numBits; - bitBuf &= (1 << numBits) - 1; + if (endianness === "be") + bitBuf >>>= excess; + else + bitBuf &= (1 << numBits) - 1; bitBufLen -= excess; this.position--; this.bitPos = 8 - excess; @@ -133,7 +141,9 @@ export default class Stream { * @returns {number} The bit mask */ function bitMask(bitPos) { - return 256 - (1 << bitPos); + return endianness === "be" ? + (1 << (8 - bitPos)) - 1 : + 256 - (1 << bitPos); } } diff --git a/src/core/operations/ParseTCP.mjs b/src/core/operations/ParseTCP.mjs new file mode 100644 index 00000000..7adb37e0 --- /dev/null +++ b/src/core/operations/ParseTCP.mjs @@ -0,0 +1,245 @@ +/** + * @author n1474335 [n1474335@gmail.com] + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import Stream from "../lib/Stream.mjs"; +import {toHexFast, fromHex} from "../lib/Hex.mjs"; +import {toBinary} from "../lib/Binary.mjs"; +import {objToTable, bytesToLargeNumber} from "../lib/Protocol.mjs"; +import Utils from "../Utils.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import BigNumber from "bignumber.js"; + +/** + * Parse TCP operation + */ +class ParseTCP extends Operation { + + /** + * ParseTCP constructor + */ + constructor() { + super(); + + this.name = "Parse TCP"; + this.module = "Default"; + this.description = "Parses a TCP header and payload (if present)."; + this.infoURL = "https://wikipedia.org/wiki/Transmission_Control_Protocol"; + this.inputType = "string"; + this.outputType = "json"; + this.presentType = "html"; + this.args = [ + { + name: "Input format", + type: "option", + value: ["Hex", "Raw"] + } + ]; + } + + /** + * @param {string} input + * @param {Object[]} args + * @returns {html} + */ + run(input, args) { + const format = args[0]; + + if (format === "Hex") { + input = fromHex(input); + } else if (format === "Raw") { + input = Utils.strToArrayBuffer(input); + } else { + throw new OperationError("Unrecognised input format."); + } + + const s = new Stream(new Uint8Array(input)); + if (s.length < 20) { + throw new OperationError("Need at least 20 bytes for a TCP Header"); + } + + // Parse Header + const TCPPacket = { + "Source port": s.readInt(2), + "Destination port": s.readInt(2), + "Sequence number": bytesToLargeNumber(s.getBytes(4)), + "Acknowledgement number": s.readInt(4), + "Data offset": s.readBits(4), + "Flags": { + "Reserved": toBinary(s.readBits(3), "", 3), + "NS": s.readBits(1), + "CWR": s.readBits(1), + "ECE": s.readBits(1), + "URG": s.readBits(1), + "ACK": s.readBits(1), + "PSH": s.readBits(1), + "RST": s.readBits(1), + "SYN": s.readBits(1), + "FIN": s.readBits(1), + }, + "Window size": s.readInt(2), + "Checksum": "0x" + toHexFast(s.getBytes(2)), + "Urgent pointer": "0x" + toHexFast(s.getBytes(2)) + }; + + // Parse options if present + let windowScaleShift = 0; + if (TCPPacket["Data offset"] > 5) { + let remainingLength = TCPPacket["Data offset"] * 4 - 20; + + const options = {}; + while (remainingLength > 0) { + const option = { + "Kind": s.readInt(1) + }; + + let opt = { name: "Reserved", length: true }; + if (Object.prototype.hasOwnProperty.call(TCP_OPTION_KIND_LOOKUP, option.Kind)) { + opt = TCP_OPTION_KIND_LOOKUP[option.Kind]; + } + + // Add Length and Value fields + if (opt.length) { + option.Length = s.readInt(1); + + if (option.Length > 2) { + if (Object.prototype.hasOwnProperty.call(opt, "parser")) { + option.Value = opt.parser(s.getBytes(option.Length - 2)); + } else { + option.Value = option.Length <= 6 ? + s.readInt(option.Length - 2): + "0x" + toHexFast(s.getBytes(option.Length - 2)); + } + + // Store Window Scale shift for later + if (option.Kind === 3 && option.Value) { + windowScaleShift = option.Value["Shift count"]; + } + } + } + options[opt.name] = option; + + const length = option.Length || 1; + remainingLength -= length; + } + TCPPacket.Options = options; + } + + if (s.hasMore()) { + TCPPacket.Data = "0x" + toHexFast(s.getBytes()); + } + + // Improve values + TCPPacket["Data offset"] = `${TCPPacket["Data offset"]} (${TCPPacket["Data offset"] * 4} bytes)`; + const trueWndSize = BigNumber(TCPPacket["Window size"]).multipliedBy(BigNumber(2).pow(BigNumber(windowScaleShift))); + TCPPacket["Window size"] = `${TCPPacket["Window size"]} (Scaled: ${trueWndSize})`; + + return TCPPacket; + } + + /** + * Displays the TCP Packet in a tabular style + * @param {Object} data + * @returns {html} + */ + present(data) { + return objToTable(data); + } + +} + +// Taken from https://www.iana.org/assignments/tcp-parameters/tcp-parameters.xhtml +// on 2022-05-30 +const TCP_OPTION_KIND_LOOKUP = { + 0: { name: "End of Option List", length: false }, + 1: { name: "No-Operation", length: false }, + 2: { name: "Maximum Segment Size", length: true }, + 3: { name: "Window Scale", length: true, parser: windowScaleParser }, + 4: { name: "SACK Permitted", length: true }, + 5: { name: "SACK", length: true }, + 6: { name: "Echo (obsoleted by option 8)", length: true }, + 7: { name: "Echo Reply (obsoleted by option 8)", length: true }, + 8: { name: "Timestamps", length: true, parser: tcpTimestampParser }, + 9: { name: "Partial Order Connection Permitted (obsolete)", length: true }, + 10: { name: "Partial Order Service Profile (obsolete)", length: true }, + 11: { name: "CC (obsolete)", length: true }, + 12: { name: "CC.NEW (obsolete)", length: true }, + 13: { name: "CC.ECHO (obsolete)", length: true }, + 14: { name: "TCP Alternate Checksum Request (obsolete)", length: true, parser: tcpAlternateChecksumParser }, + 15: { name: "TCP Alternate Checksum Data (obsolete)", length: true }, + 16: { name: "Skeeter", length: true }, + 17: { name: "Bubba", length: true }, + 18: { name: "Trailer Checksum Option", length: true }, + 19: { name: "MD5 Signature Option (obsoleted by option 29)", length: true }, + 20: { name: "SCPS Capabilities", length: true }, + 21: { name: "Selective Negative Acknowledgements", length: true }, + 22: { name: "Record Boundaries", length: true }, + 23: { name: "Corruption experienced", length: true }, + 24: { name: "SNAP", length: true }, + 25: { name: "Unassigned (released 2000-12-18)", length: true }, + 26: { name: "TCP Compression Filter", length: true }, + 27: { name: "Quick-Start Response", length: true }, + 28: { name: "User Timeout Option (also, other known unauthorized use)", length: true }, + 29: { name: "TCP Authentication Option (TCP-AO)", length: true }, + 30: { name: "Multipath TCP (MPTCP)", length: true }, + 69: { name: "Encryption Negotiation (TCP-ENO)", length: true }, + 70: { name: "Reserved (known unauthorized use without proper IANA assignment)", length: true }, + 76: { name: "Reserved (known unauthorized use without proper IANA assignment)", length: true }, + 77: { name: "Reserved (known unauthorized use without proper IANA assignment)", length: true }, + 78: { name: "Reserved (known unauthorized use without proper IANA assignment)", length: true }, + 253: { name: "RFC3692-style Experiment 1 (also improperly used for shipping products) ", length: true }, + 254: { name: "RFC3692-style Experiment 2 (also improperly used for shipping products) ", length: true } +}; + +/** + * Parses the TCP Alternate Checksum Request field + * @param {Uint8Array} data + */ +function tcpAlternateChecksumParser(data) { + const lookup = { + 0: "TCP Checksum", + 1: "8-bit Fletchers's algorithm", + 2: "16-bit Fletchers's algorithm", + 3: "Redundant Checksum Avoidance" + }[data[0]]; + + return `${lookup} (0x${toHexFast(data)})`; +} + +/** + * Parses the TCP Timestamp field + * @param {Uint8Array} data + */ +function tcpTimestampParser(data) { + const s = new Stream(data); + + if (s.length !== 8) + return `Error: Timestamp field should be 8 bytes long (received 0x${toHexFast(data)})`; + + const tsval = bytesToLargeNumber(s.getBytes(4)), + tsecr = bytesToLargeNumber(s.getBytes(4)); + + return { + "Current Timestamp": tsval, + "Echo Reply": tsecr + }; +} + +/** + * Parses the Window Scale field + * @param {Uint8Array} data + */ +function windowScaleParser(data) { + if (data.length !== 1) + return `Error: Window Scale should be one byte long (received 0x${toHexFast(data)})`; + + return { + "Shift count": data[0], + "Multiplier": 1 << data[0] + }; +} + +export default ParseTCP; diff --git a/src/core/operations/ParseUDP.mjs b/src/core/operations/ParseUDP.mjs index 0a88fd5d..2aa762ae 100644 --- a/src/core/operations/ParseUDP.mjs +++ b/src/core/operations/ParseUDP.mjs @@ -6,7 +6,9 @@ import Operation from "../Operation.mjs"; import Stream from "../lib/Stream.mjs"; -import {toHex} from "../lib/Hex.mjs"; +import {toHexFast, fromHex} from "../lib/Hex.mjs"; +import {objToTable} from "../lib/Protocol.mjs"; +import Utils from "../Utils.mjs"; import OperationError from "../errors/OperationError.mjs"; /** @@ -24,58 +26,61 @@ class ParseUDP extends Operation { this.module = "Default"; this.description = "Parses a UDP header and payload (if present)."; this.infoURL = "https://wikipedia.org/wiki/User_Datagram_Protocol"; - this.inputType = "ArrayBuffer"; + this.inputType = "string"; this.outputType = "json"; this.presentType = "html"; - this.args = []; + this.args = [ + { + name: "Input format", + type: "option", + value: ["Hex", "Raw"] + } + ]; } /** - * @param {ArrayBuffer} input + * @param {string} input + * @param {Object[]} args * @returns {Object} */ run(input, args) { - if (input.byteLength < 8) { - throw new OperationError("Need 8 bytes for a UDP Header"); + const format = args[0]; + + if (format === "Hex") { + input = fromHex(input); + } else if (format === "Raw") { + input = Utils.strToArrayBuffer(input); + } else { + throw new OperationError("Unrecognised input format."); } const s = new Stream(new Uint8Array(input)); + if (s.length < 8) { + throw new OperationError("Need 8 bytes for a UDP Header"); + } + // Parse Header const UDPPacket = { "Source port": s.readInt(2), "Destination port": s.readInt(2), "Length": s.readInt(2), - "Checksum": toHex(s.getBytes(2), "") + "Checksum": "0x" + toHexFast(s.getBytes(2)) }; // Parse data if present if (s.hasMore()) { - UDPPacket.Data = toHex(s.getBytes(UDPPacket.Length - 8), ""); + UDPPacket.Data = "0x" + toHexFast(s.getBytes(UDPPacket.Length - 8)); } return UDPPacket; } /** - * Displays the UDP Packet in a table style + * Displays the UDP Packet in a tabular style * @param {Object} data * @returns {html} */ present(data) { - const html = []; - html.push(""); - html.push(""); - html.push(""); - html.push(""); - html.push(""); - - for (const key in data) { - html.push(""); - html.push(""); - html.push(""); - html.push(""); - } - html.push("
FieldValue
" + key + "" + data[key] + "
"); - return html.join(""); + return objToTable(data); } } diff --git a/src/web/waiters/OperationsWaiter.mjs b/src/web/waiters/OperationsWaiter.mjs index 6efbab72..dee0dd06 100755 --- a/src/web/waiters/OperationsWaiter.mjs +++ b/src/web/waiters/OperationsWaiter.mjs @@ -109,11 +109,15 @@ class OperationsWaiter { const matchedOps = []; const matchedDescs = []; + // Create version with no whitespace for the fuzzy match + // Helps avoid missing matches e.g. query "TCP " would not find "Parse TCP" + const inStrNWS = inStr.replace(/\s/g, ""); + for (const opName in this.app.operations) { const op = this.app.operations[opName]; // Match op name using fuzzy match - const [nameMatch, score, idxs] = fuzzyMatch(inStr, opName); + const [nameMatch, score, idxs] = fuzzyMatch(inStrNWS, opName); // Match description based on exact match const descPos = op.description.toLowerCase().indexOf(inStr.toLowerCase()); diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 4dd469ce..67d16ab5 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -96,6 +96,7 @@ import "./tests/Protobuf.mjs"; import "./tests/ParseSSHHostKey.mjs"; import "./tests/DefangIP.mjs"; import "./tests/ParseUDP.mjs"; +import "./tests/ParseTCP.mjs"; import "./tests/AvroToJSON.mjs"; import "./tests/Lorenz.mjs"; import "./tests/LuhnChecksum.mjs"; diff --git a/tests/operations/tests/ParseTCP.mjs b/tests/operations/tests/ParseTCP.mjs new file mode 100644 index 00000000..acecb5d7 --- /dev/null +++ b/tests/operations/tests/ParseTCP.mjs @@ -0,0 +1,44 @@ +/** + * Parse TCP tests. + * + * @author n1474335 + * @copyright Crown Copyright 2022 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Parse TCP: No options", + input: "c2eb0050a138132e70dc9fb9501804025ea70000", + expectedMatch: /1026 \(Scaled: 1026\)/, + recipeConfig: [ + { + op: "Parse TCP", + args: ["Hex"], + } + ], + }, + { + name: "Parse TCP: Options", + input: "c2eb0050a1380c1f000000008002faf080950000020405b40103030801010402", + expectedMatch: /1460/, + recipeConfig: [ + { + op: "Parse TCP", + args: ["Hex"], + } + ], + }, + { + name: "Parse TCP: Timestamps", + input: "9e90e11574d57b2c00000000a002ffffe5740000020405b40402080aa4e8c8f50000000001030308", + expectedMatch: /2766719221/, + recipeConfig: [ + { + op: "Parse TCP", + args: ["Hex"], + } + ], + } +]); diff --git a/tests/operations/tests/ParseUDP.mjs b/tests/operations/tests/ParseUDP.mjs index 2c519232..6d1b5518 100644 --- a/tests/operations/tests/ParseUDP.mjs +++ b/tests/operations/tests/ParseUDP.mjs @@ -2,7 +2,6 @@ * Parse UDP tests. * * @author h345983745 - * * @copyright Crown Copyright 2019 * @license Apache-2.0 */ @@ -12,15 +11,11 @@ TestRegister.addTests([ { name: "Parse UDP: No Data - JSON", input: "04 89 00 35 00 2c 01 01", - expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0101\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x0101\"}", recipeConfig: [ - { - op: "From Hex", - args: ["Auto"], - }, { op: "Parse UDP", - args: [], + args: ["Hex"], }, { op: "JSON Minify", @@ -30,15 +25,11 @@ TestRegister.addTests([ }, { name: "Parse UDP: With Data - JSON", input: "04 89 00 35 00 2c 01 01 02 02", - expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0101\",\"Data\":\"0202\"}", + expectedOutput: "{\"Source port\":1161,\"Destination port\":53,\"Length\":44,\"Checksum\":\"0x0101\",\"Data\":\"0x0202\"}", recipeConfig: [ - { - op: "From Hex", - args: ["Auto"], - }, { op: "Parse UDP", - args: [], + args: ["Hex"], }, { op: "JSON Minify", @@ -51,13 +42,9 @@ TestRegister.addTests([ input: "04 89 00", expectedOutput: "Need 8 bytes for a UDP Header", recipeConfig: [ - { - op: "From Hex", - args: ["Auto"], - }, { op: "Parse UDP", - args: [], + args: ["Hex"], }, { op: "JSON Minify", From cf2b54e8c03788f3a1c15876048fd942168f7623 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 30 May 2022 18:14:41 +0100 Subject: [PATCH 044/111] Update CHANGELOG --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a90b36de..7ad241ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ All major and minor version changes will be documented in this file. Details of ## Details +### [9.38.0] - 2022-05-30 +- Added 'Parse TCP' operation [@n1474335] | [a895d1d] + ### [9.37.0] - 2022-03-29 - 'SM4 Encrypt' and 'SM4 Decrypt' operations added [@swesven] | [#1189] - NoPadding options added for CBC and ECB modes in AES, DES and Triple DES Decrypt operations [@swesven] | [#1189] @@ -135,7 +138,7 @@ All major and minor version changes will be documented in this file. Details of
Click to expand v8 minor versions - + ### [8.38.0] - 2019-07-03 - 'Streebog' and 'GOST hash' operations added [@MShwed] [@n1474335] | [#530] @@ -288,6 +291,7 @@ All major and minor version changes will be documented in this file. Details of +[9.38.0]: https://github.com/gchq/CyberChef/releases/tag/v9.38.0 [9.37.0]: https://github.com/gchq/CyberChef/releases/tag/v9.37.0 [9.36.0]: https://github.com/gchq/CyberChef/releases/tag/v9.36.0 [9.35.0]: https://github.com/gchq/CyberChef/releases/tag/v9.35.0 @@ -416,6 +420,7 @@ All major and minor version changes will be documented in this file. Details of [289a417]: https://github.com/gchq/CyberChef/commit/289a417dfb5923de5e1694354ec42a08d9395bfe [e9ca4dc]: https://github.com/gchq/CyberChef/commit/e9ca4dc9caf98f33fd986431cd400c88082a42b8 [dd18e52]: https://github.com/gchq/CyberChef/commit/dd18e529939078b89867297b181a584e8b2cc7da +[a895d1d]: https://github.com/gchq/CyberChef/commit/a895d1d82a2f92d440a0c5eca2bc7c898107b737 [#95]: https://github.com/gchq/CyberChef/pull/299 [#173]: https://github.com/gchq/CyberChef/pull/173 @@ -502,4 +507,4 @@ All major and minor version changes will be documented in this file. Details of [#1242]: https://github.com/gchq/CyberChef/pull/1242 [#1244]: https://github.com/gchq/CyberChef/pull/1244 [#1313]: https://github.com/gchq/CyberChef/pull/1313 -[#1326]: https://github.com/gchq/CyberChef/pull/1326 \ No newline at end of file +[#1326]: https://github.com/gchq/CyberChef/pull/1326 From cc9d51b7be8437602f32769efec6fb8f9e3652d3 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 30 May 2022 18:14:46 +0100 Subject: [PATCH 045/111] 9.38.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 16c88c1b..12bf39a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cyberchef", - "version": "9.37.3", + "version": "9.38.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "cyberchef", - "version": "9.37.3", + "version": "9.38.0", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index d2d71272..eabfaed7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cyberchef", - "version": "9.37.3", + "version": "9.38.0", "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.", "author": "n1474335 ", "homepage": "https://gchq.github.io/CyberChef", From ec577fc075380dfec5dfa33a82251e08528e599f Mon Sep 17 00:00:00 2001 From: n1474335 Date: Mon, 30 May 2022 19:25:41 +0100 Subject: [PATCH 046/111] Fixed CSS for maximising output pane --- src/web/html/index.html | 22 ++++++++++++---------- src/web/stylesheets/components/_pane.css | 15 +++++++++++---- src/web/stylesheets/layout/_controls.css | 4 ++++ src/web/stylesheets/layout/_io.css | 3 +-- src/web/waiters/OutputWaiter.mjs | 2 ++ 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/web/html/index.html b/src/web/html/index.html index 8a7adac7..d222fee1 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -176,7 +176,7 @@
Recipe - + @@ -190,7 +190,7 @@
    -
    +
    @@ -236,9 +239,7 @@ view_compact -
    -
    -
    +