mirror of
https://github.com/gchq/CyberChef.git
synced 2024-11-02 14:11:02 +01:00
Merge branch 'toHex' of https://github.com/cbeuw/CyberChef into cbeuw-toHex
This commit is contained in:
commit
3fb5bf14a6
@ -113,6 +113,7 @@ class Ingredient {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
case "number":
|
case "number":
|
||||||
|
if (data === null) return data;
|
||||||
number = parseFloat(data);
|
number = parseFloat(data);
|
||||||
if (isNaN(number)) {
|
if (isNaN(number)) {
|
||||||
const sample = Utils.truncate(data.toString(), 10);
|
const sample = Utils.truncate(data.toString(), 10);
|
||||||
|
@ -23,25 +23,42 @@ import Utils from "../Utils.mjs";
|
|||||||
*
|
*
|
||||||
* // returns "0a:14:1e"
|
* // returns "0a:14:1e"
|
||||||
* toHex([10,20,30], ":");
|
* 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) return "";
|
||||||
if (data instanceof ArrayBuffer) data = new Uint8Array(data);
|
if (data instanceof ArrayBuffer) data = new Uint8Array(data);
|
||||||
|
|
||||||
let output = "";
|
let output = "";
|
||||||
|
const prepend = (delim === "0x" || delim === "\\x");
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
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
|
// Remove the extraDelim at the end (if there is);
|
||||||
if (delim === "0x") output = "0x" + output;
|
// and remove the delim at the end, but if it's prepended there's nothing to remove
|
||||||
if (delim === "\\x") output = "\\x" + output;
|
const rTruncLen = extraDelim.length + (prepend ? 0 : delim.length);
|
||||||
|
if (rTruncLen) {
|
||||||
if (delim.length)
|
// If rTruncLen === 0 then output.slice(0,0) will be returned, which is nothing
|
||||||
return output.slice(0, -delim.length);
|
return output.slice(0, -rTruncLen);
|
||||||
else
|
} else {
|
||||||
return output;
|
return output;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -87,7 +104,7 @@ export function toHexFast(data) {
|
|||||||
*/
|
*/
|
||||||
export function fromHex(data, delim="Auto", byteLen=2) {
|
export function fromHex(data, delim="Auto", byteLen=2) {
|
||||||
if (delim !== "None") {
|
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, "");
|
data = data.replace(delimRegex, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation.mjs";
|
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";
|
import Utils from "../Utils.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,7 +29,12 @@ class ToHex extends Operation {
|
|||||||
{
|
{
|
||||||
name: "Delimiter",
|
name: "Delimiter",
|
||||||
type: "option",
|
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
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -40,8 +45,16 @@ class ToHex extends Operation {
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const delim = Utils.charRep(args[0] || "Space");
|
let delim, comma;
|
||||||
return toHex(new Uint8Array(input), delim, 2);
|
if (args[0] === "0x with comma") {
|
||||||
|
delim = "0x";
|
||||||
|
comma = ",";
|
||||||
|
} else {
|
||||||
|
delim = Utils.charRep(args[0] || "Space");
|
||||||
|
}
|
||||||
|
const lineSize = args[1];
|
||||||
|
|
||||||
|
return toHex(new Uint8Array(input), delim, 2, comma, lineSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,17 +67,31 @@ class ToHex extends Operation {
|
|||||||
* @returns {Object[]} pos
|
* @returns {Object[]} pos
|
||||||
*/
|
*/
|
||||||
highlight(pos, args) {
|
highlight(pos, args) {
|
||||||
const delim = Utils.charRep(args[0] || "Space"),
|
let delim, commaLen;
|
||||||
len = delim === "\r\n" ? 1 : delim.length;
|
if (args[0] === "0x with comma") {
|
||||||
|
delim = "0x";
|
||||||
pos[0].start = pos[0].start * (2 + len);
|
commaLen = 1;
|
||||||
pos[0].end = pos[0].end * (2 + len) - len;
|
} else {
|
||||||
|
delim = Utils.charRep(args[0] || "Space");
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
return (p / lineSize | 0) - (p >= lineSize && p % lineSize === 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
pos[0].end -= commaLen;
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,20 +105,26 @@ class ToHex extends Operation {
|
|||||||
* @returns {Object[]} pos
|
* @returns {Object[]} pos
|
||||||
*/
|
*/
|
||||||
highlightReverse(pos, args) {
|
highlightReverse(pos, args) {
|
||||||
const delim = Utils.charRep(args[0] || "Space"),
|
let delim, commaLen;
|
||||||
len = delim === "\r\n" ? 1 : delim.length,
|
if (args[0] === "0x with comma") {
|
||||||
width = len + 2;
|
delim = "0x";
|
||||||
|
commaLen = 1;
|
||||||
// 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
|
} else {
|
||||||
if (delim === "0x" || delim === "\\x") {
|
delim = Utils.charRep(args[0] || "Space");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pos[0].start = pos[0].start === 0 ? 0 : Math.round(pos[0].start / width);
|
const lineSize = args[1],
|
||||||
pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / width);
|
len = (delim === "\r\n" ? 1 : delim.length) + commaLen,
|
||||||
|
width = len + 2;
|
||||||
|
|
||||||
|
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 - 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;
|
return pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ import "./tests/Gzip.mjs";
|
|||||||
import "./tests/Gunzip.mjs";
|
import "./tests/Gunzip.mjs";
|
||||||
import "./tests/Hash.mjs";
|
import "./tests/Hash.mjs";
|
||||||
import "./tests/HaversineDistance.mjs";
|
import "./tests/HaversineDistance.mjs";
|
||||||
|
import "./tests/Hex.mjs";
|
||||||
import "./tests/Hexdump.mjs";
|
import "./tests/Hexdump.mjs";
|
||||||
import "./tests/Image.mjs";
|
import "./tests/Image.mjs";
|
||||||
import "./tests/IndexOfCoincidence.mjs";
|
import "./tests/IndexOfCoincidence.mjs";
|
||||||
|
97
tests/operations/tests/Hex.mjs
Normal file
97
tests/operations/tests/Hex.mjs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import TestRegister from "../../lib/TestRegister.mjs";
|
||||||
|
|
||||||
|
TestRegister.addTests([
|
||||||
|
{
|
||||||
|
name: "ASCII to Hex stream",
|
||||||
|
input: "aberystwyth",
|
||||||
|
expectedOutput: "6162657279737477797468",
|
||||||
|
recipeConfig: [
|
||||||
|
{
|
||||||
|
"op": "To Hex",
|
||||||
|
"args": [
|
||||||
|
"None",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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 with comma",
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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 with comma",
|
||||||
|
4
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
]);
|
Loading…
Reference in New Issue
Block a user