From 597fba2fd0a5edd318f8586b5e4a19078466d94b Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Wed, 15 Jan 2020 00:14:43 +0000 Subject: [PATCH 01/10] Add line size formatting and comma separation --- src/core/lib/Hex.mjs | 35 ++++++++++++++++++++++++++--------- src/core/operations/ToHex.mjs | 13 ++++++++++++- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/core/lib/Hex.mjs b/src/core/lib/Hex.mjs index 5ae06a7e..0274f876 100644 --- a/src/core/lib/Hex.mjs +++ b/src/core/lib/Hex.mjs @@ -23,25 +23,42 @@ import Utils from "../Utils.mjs"; * * // returns "0a:14:1e" * toHex([10,20,30], ":"); + * + * // returns "0x0a,0x14,0x1e" + * toHex([10,20,30], "0x", 2, ",") */ -export function toHex(data, delim=" ", padding=2) { +export function toHex(data, delim=" ", padding=2, extraDelim="", lineSize=0) { if (!data) return ""; if (data instanceof ArrayBuffer) data = new Uint8Array(data); let output = ""; + const prepend = (delim === "0x" || delim === "\\x"); for (let i = 0; i < data.length; i++) { - output += data[i].toString(16).padStart(padding, "0") + delim; + const hex = data[i].toString(16).padStart(padding, "0"); + if (prepend) { + output += delim + hex; + } else { + output += hex + delim; + } + if (extraDelim) { + output += extraDelim; + } + // Add LF after each lineSize amount of bytes but not at the end + if ((i !== data.length - 1) && ((i + 1) % lineSize === 0)) { + output += "\n"; + } } - // Add \x or 0x to beginning - if (delim === "0x") output = "0x" + output; - if (delim === "\\x") output = "\\x" + output; - - if (delim.length) - return output.slice(0, -delim.length); - else + // Remove the extraDelim at the end (if there is); + // and remove the delim at the end, but if it's prepended there's nothing to remove + const rTruncLen = extraDelim.length + (prepend ? 0 : delim.length); + if (rTruncLen) { + // If rTruncLen === 0 then output.slice(0,0) will be returned, which is nothing + return output.slice(0, -rTruncLen); + } else { return output; + } } diff --git a/src/core/operations/ToHex.mjs b/src/core/operations/ToHex.mjs index 6ae48da9..b2712b40 100644 --- a/src/core/operations/ToHex.mjs +++ b/src/core/operations/ToHex.mjs @@ -30,6 +30,16 @@ class ToHex extends Operation { name: "Delimiter", type: "option", value: TO_HEX_DELIM_OPTIONS + }, + { + name: "Bytes per line", + type: "number", + value: 0 + }, + { + name: "Comma separated", + type: "boolean", + value: false } ]; } @@ -41,7 +51,8 @@ class ToHex extends Operation { */ run(input, args) { const delim = Utils.charRep(args[0] || "Space"); - return toHex(new Uint8Array(input), delim, 2); + const comma = args[2] ? "," : ""; + return toHex(new Uint8Array(input), delim, 2, comma, args[1]); } /** From 41c8a5aff0a95d7cb8a12d204269b568a9cb0964 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Wed, 15 Jan 2020 22:20:47 +0000 Subject: [PATCH 02/10] fromHex can now extract 0x format --- src/core/lib/Hex.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/lib/Hex.mjs b/src/core/lib/Hex.mjs index 0274f876..0108eabd 100644 --- a/src/core/lib/Hex.mjs +++ b/src/core/lib/Hex.mjs @@ -104,7 +104,7 @@ export function toHexFast(data) { */ export function fromHex(data, delim="Auto", byteLen=2) { if (delim !== "None") { - const delimRegex = delim === "Auto" ? /[^a-f\d]/gi : Utils.regexRep(delim); + const delimRegex = delim === "Auto" ? /[^a-f\d]|(0x)/gi : Utils.regexRep(delim); data = data.replace(delimRegex, ""); } From 1d8c7dcb970cb9d40bf76803c08661fb0dbc7f05 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Wed, 15 Jan 2020 23:29:18 +0000 Subject: [PATCH 03/10] Allow output highlighting --- src/core/operations/ToHex.mjs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/core/operations/ToHex.mjs b/src/core/operations/ToHex.mjs index b2712b40..f2c308b2 100644 --- a/src/core/operations/ToHex.mjs +++ b/src/core/operations/ToHex.mjs @@ -66,15 +66,25 @@ class ToHex extends Operation { */ highlight(pos, args) { const delim = Utils.charRep(args[0] || "Space"), - len = delim === "\r\n" ? 1 : delim.length; + lineSize = args[1], + comma = args[2], + len = (delim === "\r\n" ? 1 : delim.length) + (comma ? 1 : 0); - pos[0].start = pos[0].start * (2 + len); - pos[0].end = pos[0].end * (2 + len) - len; + const countLF = function(p) { + // Count the number of LFs from 0 upto p + return (p / lineSize | 0) - (p >= lineSize && p % lineSize === 0); + }; - // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly - if (delim === "0x" || delim === "\\x") { - pos[0].start += 2; - pos[0].end += 2; + pos[0].start = pos[0].start * (2 + len) + countLF(pos[0].start); + pos[0].end = pos[0].end * (2 + len) + countLF(pos[0].end); + + // if the deliminators are not prepended, trim the trailing deliminator + if (!(delim === "0x" || delim === "\\x")) { + pos[0].end -= delim.length; + } + // if there is comma, trim the trailing comma + if (comma) { + pos[0].end--; } return pos; } From 6dbaf6a36c8b129b98b1434bd9986bd0d5c4338e Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 17 Jan 2020 12:48:21 +0000 Subject: [PATCH 04/10] reverse highlight --- src/core/operations/ToHex.mjs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/core/operations/ToHex.mjs b/src/core/operations/ToHex.mjs index f2c308b2..996eacfa 100644 --- a/src/core/operations/ToHex.mjs +++ b/src/core/operations/ToHex.mjs @@ -100,19 +100,19 @@ class ToHex extends Operation { */ highlightReverse(pos, args) { const delim = Utils.charRep(args[0] || "Space"), - len = delim === "\r\n" ? 1 : delim.length, + lineSize = args[1], + comma = args[2], + len = (delim === "\r\n" ? 1 : delim.length) + (comma ? 1 : 0), width = len + 2; - // 0x and \x are added to the beginning if they are selected, so increment the positions accordingly - if (delim === "0x" || delim === "\\x") { - if (pos[0].start > 1) pos[0].start -= 2; - else pos[0].start = 0; - if (pos[0].end > 1) pos[0].end -= 2; - else pos[0].end = 0; - } + const countLF = function(p) { + // Count the number of LFs from 0 up to p + const lineLength = width * lineSize; + return (p / lineLength | 0) - (p >= lineLength && p % lineLength === 0); + }; - pos[0].start = pos[0].start === 0 ? 0 : Math.round(pos[0].start / width); - pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / width); + pos[0].start = pos[0].start === 0 ? 0 : Math.round((pos[0].start - countLF(pos[0].start)) / width); + pos[0].end = pos[0].end === 0 ? 0 : Math.ceil((pos[0].end - countLF(pos[0].end)) / width); return pos; } } From 23956480b724aa2a763186e14f6e3ebfb6ee7405 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Fri, 17 Jan 2020 18:47:46 +0000 Subject: [PATCH 05/10] Variable name --- src/core/operations/ToHex.mjs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/operations/ToHex.mjs b/src/core/operations/ToHex.mjs index 996eacfa..8c9297f5 100644 --- a/src/core/operations/ToHex.mjs +++ b/src/core/operations/ToHex.mjs @@ -51,8 +51,10 @@ class ToHex extends Operation { */ run(input, args) { const delim = Utils.charRep(args[0] || "Space"); + const lineSize = args[1]; const comma = args[2] ? "," : ""; - return toHex(new Uint8Array(input), delim, 2, comma, args[1]); + + return toHex(new Uint8Array(input), delim, 2, comma, lineSize); } /** From 55dddd3ef969a9bcfee13701c7cd02e826878fd4 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 18 Jan 2020 00:21:15 +0000 Subject: [PATCH 06/10] Add tests --- tests/operations/index.mjs | 1 + tests/operations/tests/Hex.mjs | 101 +++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 tests/operations/tests/Hex.mjs diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index bf440414..3257905d 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -45,6 +45,7 @@ import "./tests/Gzip.mjs"; import "./tests/Gunzip.mjs"; import "./tests/Hash.mjs"; import "./tests/HaversineDistance.mjs"; +import "./tests/Hex.mjs"; import "./tests/Hexdump.mjs"; import "./tests/Image.mjs"; import "./tests/IndexOfCoincidence.mjs"; diff --git a/tests/operations/tests/Hex.mjs b/tests/operations/tests/Hex.mjs new file mode 100644 index 00000000..9d55c411 --- /dev/null +++ b/tests/operations/tests/Hex.mjs @@ -0,0 +1,101 @@ +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "ASCII to Hex stream", + input: "aberystwyth", + expectedOutput: "6162657279737477797468", + recipeConfig: [ + { + "op": "To Hex", + "args": [ + "None", + 0, + false + ] + }, + ] + }, + { + name: "ASCII to Hex with colon deliminator ", + input: "aberystwyth", + expectedOutput: "61:62:65:72:79:73:74:77:79:74:68", + recipeConfig: [ + { + "op": "To Hex", + "args": [ + "Colon", + 0, + false + ] + } + ] + }, + { + name: "ASCII to 0x Hex with comma", + input: "aberystwyth", + expectedOutput: "0x61,0x62,0x65,0x72,0x79,0x73,0x74,0x77,0x79,0x74,0x68", + recipeConfig: [ + { + "op": "To Hex", + "args": [ + "0x", + 0, + true + ] + } + ] + }, + { + name: "ASCII to 0x Hex with comma and line breaks", + input: "aberystwyth", + expectedOutput: "0x61,0x62,0x65,0x72,\n0x79,0x73,0x74,0x77,\n0x79,0x74,0x68", + recipeConfig: [ + { + "op": "To Hex", + "args": [ + "0x", + 4, + true + ] + } + ] + }, + { + name: "Hex stream to UTF-8", + input: "e69591e69591e5ada9e5ad90", + expectedOutput: "救救孩子", + recipeConfig: [ + { + "op": "From Hex", + "args": [ + "Auto" + ] + } + ] + + }, + { + name: "Multiline 0x hex to ASCII", + input: "0x49,0x20,0x73,0x61,0x77,0x20,0x6d,0x79,0x73,0x65,0x6c,0x66,0x20,0x73,0x69,\ +0x74,0x74,0x69,0x6e,0x67,0x20,0x69,0x6e,0x20,0x74,0x68,0x65,0x20,0x63,0x72,\ +0x6f,0x74,0x63,0x68,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x74,0x68,0x69,\ +0x73,0x20,0x66,0x69,0x67,0x20,0x74,0x72,0x65,0x65,0x2c,0x20,0x73,0x74,0x61,\ +0x72,0x76,0x69,0x6e,0x67,0x20,0x74,0x6f,0x20,0x64,0x65,0x61,0x74,0x68,0x2c,\ +0x20,0x6a,0x75,0x73,0x74,0x20,0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x49,\ +0x20,0x63,0x6f,0x75,0x6c,0x64,0x6e,0x27,0x74,0x20,0x6d,0x61,0x6b,0x65,0x20,\ +0x75,0x70,0x20,0x6d,0x79,0x20,0x6d,0x69,0x6e,0x64,0x20,0x77,0x68,0x69,0x63,\ +0x68,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x66,0x69,0x67,0x73,0x20,0x49,\ +0x20,0x77,0x6f,0x75,0x6c,0x64,0x20,0x63,0x68,0x6f,0x6f,0x73,0x65,0x2e", + expectedOutput: "I saw myself sitting in the crotch of the this fig tree, starving to death, just because I couldn't make up my mind which of the figs I would choose.", + recipeConfig: [ + { + "op": "From Hex", + "args": [ + "Auto" + ] + } + ] + + } +]); From 9a3464a5ec0f0e00dd7731e69faa9d2af1f68674 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 18 Jan 2020 13:19:28 +0000 Subject: [PATCH 07/10] Fix ingredient type conversion for null number --- src/core/Ingredient.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/Ingredient.mjs b/src/core/Ingredient.mjs index f74b42d6..da9c664b 100755 --- a/src/core/Ingredient.mjs +++ b/src/core/Ingredient.mjs @@ -113,6 +113,7 @@ class Ingredient { return data; } case "number": + if (data === null) return 0; number = parseFloat(data); if (isNaN(number)) { const sample = Utils.truncate(data.toString(), 10); From 293a95e938e120aa2d2f246240ea2d524d0e6497 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 18 Jan 2020 13:55:32 +0000 Subject: [PATCH 08/10] Remove tickbox and make 0x comma an option --- src/core/operations/ToHex.mjs | 50 ++++++++++++++++++++-------------- tests/operations/tests/Hex.mjs | 16 ++++------- 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/src/core/operations/ToHex.mjs b/src/core/operations/ToHex.mjs index 8c9297f5..25d4e059 100644 --- a/src/core/operations/ToHex.mjs +++ b/src/core/operations/ToHex.mjs @@ -5,7 +5,7 @@ */ import Operation from "../Operation.mjs"; -import {toHex, TO_HEX_DELIM_OPTIONS} from "../lib/Hex.mjs"; +import {toHex} from "../lib/Hex.mjs"; import Utils from "../Utils.mjs"; /** @@ -29,17 +29,12 @@ class ToHex extends Operation { { name: "Delimiter", type: "option", - value: TO_HEX_DELIM_OPTIONS + value: ["Space", "Percent", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "0x with comma", "\\x", "None"] }, { name: "Bytes per line", type: "number", value: 0 - }, - { - name: "Comma separated", - type: "boolean", - value: false } ]; } @@ -50,9 +45,14 @@ class ToHex extends Operation { * @returns {string} */ run(input, args) { - const delim = Utils.charRep(args[0] || "Space"); + let delim, comma; + if (args[0] === "0x with comma") { + delim = "0x"; + comma = ","; + } else { + delim = Utils.charRep(args[0] || "Space"); + } const lineSize = args[1]; - const comma = args[2] ? "," : ""; return toHex(new Uint8Array(input), delim, 2, comma, lineSize); } @@ -67,10 +67,16 @@ class ToHex extends Operation { * @returns {Object[]} pos */ highlight(pos, args) { - const delim = Utils.charRep(args[0] || "Space"), - lineSize = args[1], - comma = args[2], - len = (delim === "\r\n" ? 1 : delim.length) + (comma ? 1 : 0); + let delim, commaLen; + if (args[0] === "0x with comma") { + delim = "0x"; + commaLen = 1; + } else { + delim = Utils.charRep(args[0] || "Space"); + } + + const lineSize = args[1], + len = (delim === "\r\n" ? 1 : delim.length) + commaLen; const countLF = function(p) { // Count the number of LFs from 0 upto p @@ -85,9 +91,7 @@ class ToHex extends Operation { pos[0].end -= delim.length; } // if there is comma, trim the trailing comma - if (comma) { - pos[0].end--; - } + pos[0].end -= commaLen; return pos; } @@ -101,10 +105,16 @@ class ToHex extends Operation { * @returns {Object[]} pos */ highlightReverse(pos, args) { - const delim = Utils.charRep(args[0] || "Space"), - lineSize = args[1], - comma = args[2], - len = (delim === "\r\n" ? 1 : delim.length) + (comma ? 1 : 0), + let delim, commaLen; + if (args[0] === "0x with comma") { + delim = "0x"; + commaLen = 1; + } else { + delim = Utils.charRep(args[0] || "Space"); + } + + const lineSize = args[1], + len = (delim === "\r\n" ? 1 : delim.length) + commaLen, width = len + 2; const countLF = function(p) { diff --git a/tests/operations/tests/Hex.mjs b/tests/operations/tests/Hex.mjs index 9d55c411..91520d88 100644 --- a/tests/operations/tests/Hex.mjs +++ b/tests/operations/tests/Hex.mjs @@ -10,8 +10,7 @@ TestRegister.addTests([ "op": "To Hex", "args": [ "None", - 0, - false + 0 ] }, ] @@ -25,8 +24,7 @@ TestRegister.addTests([ "op": "To Hex", "args": [ "Colon", - 0, - false + 0 ] } ] @@ -39,9 +37,8 @@ TestRegister.addTests([ { "op": "To Hex", "args": [ - "0x", - 0, - true + "0x with comma", + 0 ] } ] @@ -54,9 +51,8 @@ TestRegister.addTests([ { "op": "To Hex", "args": [ - "0x", - 4, - true + "0x with comma", + 4 ] } ] From 1197859865ccc9dd7b31ee68b95ce101f5edc4c5 Mon Sep 17 00:00:00 2001 From: Andy Wang Date: Sat, 18 Jan 2020 14:56:17 +0000 Subject: [PATCH 09/10] Preserve null data when type is number in prepare --- src/core/Ingredient.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/Ingredient.mjs b/src/core/Ingredient.mjs index da9c664b..d64bf763 100755 --- a/src/core/Ingredient.mjs +++ b/src/core/Ingredient.mjs @@ -113,7 +113,7 @@ class Ingredient { return data; } case "number": - if (data === null) return 0; + if (data === null) return data; number = parseFloat(data); if (isNaN(number)) { const sample = Utils.truncate(data.toString(), 10); From c2212f9ab36cb41672fb2f7946501d2532f4f424 Mon Sep 17 00:00:00 2001 From: n1474335 Date: Thu, 13 Feb 2020 14:17:43 +0000 Subject: [PATCH 10/10] Tidied up To Hex mods --- src/core/lib/Hex.mjs | 11 ++++------- src/core/operations/ToHex.mjs | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/core/lib/Hex.mjs b/src/core/lib/Hex.mjs index 0108eabd..9c70e91c 100644 --- a/src/core/lib/Hex.mjs +++ b/src/core/lib/Hex.mjs @@ -36,11 +36,8 @@ export function toHex(data, delim=" ", padding=2, extraDelim="", lineSize=0) { for (let i = 0; i < data.length; i++) { const hex = data[i].toString(16).padStart(padding, "0"); - if (prepend) { - output += delim + hex; - } else { - output += hex + delim; - } + output += prepend ? delim + hex : hex + delim; + if (extraDelim) { output += extraDelim; } @@ -50,7 +47,7 @@ export function toHex(data, delim=" ", padding=2, extraDelim="", lineSize=0) { } } - // Remove the extraDelim at the end (if there is); + // Remove the extraDelim at the end (if there is one) // and remove the delim at the end, but if it's prepended there's nothing to remove const rTruncLen = extraDelim.length + (prepend ? 0 : delim.length); if (rTruncLen) { @@ -119,7 +116,7 @@ export function fromHex(data, delim="Auto", byteLen=2) { /** * To Hexadecimal delimiters. */ -export const TO_HEX_DELIM_OPTIONS = ["Space", "Percent", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"]; +export const TO_HEX_DELIM_OPTIONS = ["Space", "Percent", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "0x with comma", "\\x", "None"]; /** diff --git a/src/core/operations/ToHex.mjs b/src/core/operations/ToHex.mjs index 25d4e059..2e97de8f 100644 --- a/src/core/operations/ToHex.mjs +++ b/src/core/operations/ToHex.mjs @@ -5,7 +5,7 @@ */ import Operation from "../Operation.mjs"; -import {toHex} from "../lib/Hex.mjs"; +import {toHex, TO_HEX_DELIM_OPTIONS} from "../lib/Hex.mjs"; import Utils from "../Utils.mjs"; /** @@ -29,7 +29,7 @@ class ToHex extends Operation { { name: "Delimiter", type: "option", - value: ["Space", "Percent", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "0x with comma", "\\x", "None"] + value: TO_HEX_DELIM_OPTIONS }, { name: "Bytes per line",