cyberchef 10.22.0 → 10.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +131 -0
- package/CONTRIBUTING.md +37 -0
- package/Dockerfile +2 -0
- package/Gruntfile.js +0 -12
- package/README.md +1 -1
- package/babel.config.js +0 -6
- package/package.json +63 -62
- package/src/core/Chef.mjs +8 -1
- package/src/core/Ingredient.mjs +5 -2
- package/src/core/Operation.mjs +6 -1
- package/src/core/Recipe.mjs +10 -5
- package/src/core/config/Categories.json +18 -3
- package/src/core/config/OperationConfig.json +22310 -0
- package/src/core/config/modules/Bletchley.mjs +28 -0
- package/src/core/config/modules/Charts.mjs +24 -0
- package/src/core/config/modules/Ciphers.mjs +128 -0
- package/src/core/config/modules/Code.mjs +60 -0
- package/src/core/config/modules/Compression.mjs +52 -0
- package/src/core/config/modules/Crypto.mjs +134 -0
- package/src/core/config/modules/Default.mjs +424 -0
- package/src/core/config/modules/Diff.mjs +16 -0
- package/src/core/config/modules/Encodings.mjs +42 -0
- package/src/core/config/modules/Handlebars.mjs +16 -0
- package/src/core/config/modules/Hashing.mjs +30 -0
- package/src/core/config/modules/Image.mjs +70 -0
- package/src/core/config/modules/Jq.mjs +16 -0
- package/src/core/config/modules/OCR.mjs +16 -0
- package/src/core/config/modules/OpModules.mjs +63 -0
- package/src/core/config/modules/PGP.mjs +26 -0
- package/src/core/config/modules/Protobuf.mjs +18 -0
- package/src/core/config/modules/PublicKey.mjs +36 -0
- package/src/core/config/modules/Regex.mjs +40 -0
- package/src/core/config/modules/Serialise.mjs +26 -0
- package/src/core/config/modules/Shellcode.mjs +18 -0
- package/src/core/config/modules/URL.mjs +20 -0
- package/src/core/config/modules/UserAgent.mjs +16 -0
- package/src/core/config/modules/Yara.mjs +16 -0
- package/src/core/lib/AudioBytes.mjs +103 -0
- package/src/core/lib/AudioMetaSchema.mjs +82 -0
- package/src/core/lib/AudioParsers.mjs +630 -0
- package/src/core/lib/BigIntUtils.mjs +73 -0
- package/src/core/lib/Modhex.mjs +2 -0
- package/src/core/lib/QRCode.mjs +30 -10
- package/src/core/lib/RC6.mjs +625 -0
- package/src/core/operations/A1Z26CipherDecode.mjs +1 -1
- package/src/core/operations/AddTextToImage.mjs +116 -64
- package/src/core/operations/BlurImage.mjs +10 -12
- package/src/core/operations/ContainImage.mjs +50 -40
- package/src/core/operations/ConvertImageFormat.mjs +33 -39
- package/src/core/operations/CoverImage.mjs +39 -37
- package/src/core/operations/CropImage.mjs +35 -21
- package/src/core/operations/DisassembleARM.mjs +193 -0
- package/src/core/operations/DitherImage.mjs +8 -8
- package/src/core/operations/EscapeUnicodeCharacters.mjs +0 -17
- package/src/core/operations/ExtractAudioMetadata.mjs +175 -0
- package/src/core/operations/ExtractLSB.mjs +17 -11
- package/src/core/operations/ExtractRGBA.mjs +12 -10
- package/src/core/operations/FlaskSessionDecode.mjs +80 -0
- package/src/core/operations/FlaskSessionSign.mjs +89 -0
- package/src/core/operations/FlaskSessionVerify.mjs +136 -0
- package/src/core/operations/FlipImage.mjs +14 -10
- package/src/core/operations/GenerateImage.mjs +39 -32
- package/src/core/operations/ImageBrightnessContrast.mjs +10 -10
- package/src/core/operations/ImageFilter.mjs +14 -13
- package/src/core/operations/ImageHueSaturationLightness.mjs +22 -20
- package/src/core/operations/ImageOpacity.mjs +6 -8
- package/src/core/operations/InvertImage.mjs +4 -6
- package/src/core/operations/Jq.mjs +12 -4
- package/src/core/operations/NormaliseImage.mjs +5 -7
- package/src/core/operations/OffsetChecker.mjs +1 -1
- package/src/core/operations/ParseEthernetFrame.mjs +112 -0
- package/src/core/operations/ParseIPv4Header.mjs +23 -6
- package/src/core/operations/ParseQRCode.mjs +13 -13
- package/src/core/operations/PseudoRandomIntegerGenerator.mjs +164 -0
- package/src/core/operations/RC6Decrypt.mjs +119 -0
- package/src/core/operations/RC6Encrypt.mjs +119 -0
- package/src/core/operations/RandomizeColourPalette.mjs +11 -11
- package/src/core/operations/ResizeImage.mjs +30 -23
- package/src/core/operations/RotateImage.mjs +8 -9
- package/src/core/operations/SQLBeautify.mjs +21 -3
- package/src/core/operations/SharpenImage.mjs +94 -62
- package/src/core/operations/SplitColourChannels.mjs +47 -21
- package/src/core/operations/TextIntegerConverter.mjs +123 -0
- package/src/core/operations/UnescapeUnicodeCharacters.mjs +17 -0
- package/src/core/operations/ViewBitPlane.mjs +16 -20
- package/src/core/operations/index.mjs +960 -0
- package/src/node/index.mjs +2423 -0
- package/src/web/HTMLIngredient.mjs +24 -43
- package/src/web/Manager.mjs +1 -0
- package/src/web/html/index.html +6 -6
- package/src/web/static/fonts/bmfonts/Roboto72White.fnt +491 -485
- package/src/web/static/fonts/bmfonts/RobotoBlack72White.fnt +494 -488
- package/src/web/static/fonts/bmfonts/RobotoMono72White.fnt +110 -103
- package/src/web/static/fonts/bmfonts/RobotoSlab72White.fnt +498 -492
- package/src/web/stylesheets/layout/_banner.css +30 -0
- package/src/web/stylesheets/layout/_modals.css +5 -0
- package/src/web/stylesheets/utils/_overrides.css +7 -0
- package/src/web/waiters/ControlsWaiter.mjs +82 -0
- package/src/web/waiters/InputWaiter.mjs +12 -6
- package/src/web/waiters/RecipeWaiter.mjs +2 -2
- package/tests/browser/02_ops.js +23 -3
- package/tests/node/index.mjs +1 -0
- package/tests/node/tests/lib/BigIntUtils.mjs +150 -0
- package/tests/node/tests/operations.mjs +9 -7
- package/tests/operations/index.mjs +8 -0
- package/tests/operations/tests/A1Z26CipherDecode.mjs +33 -0
- package/tests/operations/tests/DisassembleARM.mjs +377 -0
- package/tests/operations/tests/ExtractAudioMetadata.mjs +287 -0
- package/tests/operations/tests/FlaskSession.mjs +246 -0
- package/tests/operations/tests/GenerateQRCode.mjs +67 -0
- package/tests/operations/tests/JWTSign.mjs +83 -8
- package/tests/operations/tests/Jq.mjs +32 -0
- package/tests/operations/tests/Modhex.mjs +20 -0
- package/tests/operations/tests/ParseEthernetFrame.mjs +45 -0
- package/tests/operations/tests/RC6.mjs +487 -0
- package/tests/operations/tests/SQLBeautify.mjs +54 -0
- package/tests/operations/tests/TextIntegerConverter.mjs +199 -0
- package/tests/samples/Audio.mjs +73 -0
- package/tests/samples/Images.mjs +0 -12
- package/webpack.config.js +10 -7
- package/src/core/lib/ImageManipulation.mjs +0 -251
|
@@ -26,6 +26,36 @@
|
|
|
26
26
|
color: var(--banner-url-colour);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
#options:focus {
|
|
30
|
+
background-color: #eef3ec;
|
|
31
|
+
border: solid black 2px;
|
|
32
|
+
border-radius: 4px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#support:focus {
|
|
36
|
+
background-color: #eef3ec;
|
|
37
|
+
border: solid black 2px;
|
|
38
|
+
border-radius: 4px;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#notice:focus {
|
|
42
|
+
background-color: #eef3ec;
|
|
43
|
+
border: solid black 2px;
|
|
44
|
+
border-radius: 4px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
#banner .col a:focus {
|
|
48
|
+
background-color: #eef3ec;
|
|
49
|
+
border: solid black 2px;
|
|
50
|
+
border-radius: 4px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
#notice-wrapper #notice:focus {
|
|
54
|
+
background-color: #eef3ec;
|
|
55
|
+
border: solid black 2px;
|
|
56
|
+
border-radius: 4px;
|
|
57
|
+
}
|
|
58
|
+
|
|
29
59
|
#notice-wrapper {
|
|
30
60
|
text-align: center;
|
|
31
61
|
overflow: hidden;
|
|
@@ -78,6 +78,11 @@
|
|
|
78
78
|
border-left: 2px solid var(--primary-border-colour);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
p a:focus {
|
|
82
|
+
color: #0a6ebd;
|
|
83
|
+
text-decoration: underline;
|
|
84
|
+
}
|
|
85
|
+
|
|
81
86
|
.checkbox label input[type=checkbox]+.checkbox-decorator .check,
|
|
82
87
|
.checkbox label input[type=checkbox]+.checkbox-decorator .check::before {
|
|
83
88
|
border-color: var(--input-border-colour);
|
|
@@ -57,6 +57,18 @@ class ControlsWaiter {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Checks or unchecks the Auto Bake checkbox with "Enter"
|
|
62
|
+
* @param {Event} ev
|
|
63
|
+
*/
|
|
64
|
+
autoBakeKeyboardHandler(ev) {
|
|
65
|
+
const checkBox = document.getElementById("auto-bake");
|
|
66
|
+
ev.preventDefault();
|
|
67
|
+
if (ev.key === "Enter" || ev.key === " ") {
|
|
68
|
+
checkBox.checked = !checkBox.checked;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
60
72
|
|
|
61
73
|
/**
|
|
62
74
|
* Handler to trigger baking.
|
|
@@ -387,6 +399,18 @@ class ControlsWaiter {
|
|
|
387
399
|
*/
|
|
388
400
|
supportButtonClick(e) {
|
|
389
401
|
e.preventDefault();
|
|
402
|
+
const faqs = document.getElementById("faqs");
|
|
403
|
+
const faqsAElement = faqs.getElementsByTagName("a");
|
|
404
|
+
for (let i = 0; i < faqsAElement.length; i++) {
|
|
405
|
+
faqsAElement[i].setAttribute("tabindex", "0");
|
|
406
|
+
faqsAElement[i].addEventListener("keydown", this.navigateFAQList, false);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const tabs = document.querySelectorAll('[role="tab"]');
|
|
410
|
+
|
|
411
|
+
for (let i = 0; i < tabs.length; i++) {
|
|
412
|
+
tabs[i].addEventListener("keydown", this.changeTabs, false);
|
|
413
|
+
}
|
|
390
414
|
|
|
391
415
|
const reportBugInfo = document.getElementById("report-bug-info");
|
|
392
416
|
const saveLink = this.generateStateUrl(true, true, null, null, "https://gchq.github.io/CyberChef/");
|
|
@@ -403,6 +427,64 @@ ${navigator.userAgent}
|
|
|
403
427
|
}
|
|
404
428
|
|
|
405
429
|
|
|
430
|
+
/**
|
|
431
|
+
* @param {Event} ev
|
|
432
|
+
*/
|
|
433
|
+
changeTabs(ev) {
|
|
434
|
+
const tab = ev.target;
|
|
435
|
+
ev.preventDefault();
|
|
436
|
+
ev.stopPropagation();
|
|
437
|
+
|
|
438
|
+
if (ev.key === "ArrowRight") {
|
|
439
|
+
const nextTab = tab.parentElement;
|
|
440
|
+
if (nextTab.nextElementSibling === null) {
|
|
441
|
+
tab.parentElement.parentElement.firstElementChild.firstElementChild.focus();
|
|
442
|
+
} else {
|
|
443
|
+
nextTab.nextElementSibling.firstElementChild.focus();
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
} else if (ev.key === "ArrowLeft") {
|
|
447
|
+
const prevTab = tab.parentElement;
|
|
448
|
+
|
|
449
|
+
if (prevTab.previousElementSibling === null) {
|
|
450
|
+
tab.parentElement.parentElement.lastElementChild.firstElementChild.focus();
|
|
451
|
+
} else {
|
|
452
|
+
prevTab.previousElementSibling.firstElementChild.focus();
|
|
453
|
+
}
|
|
454
|
+
} else if (ev.key === "Tab" && !ev.shiftKey && ev.target === document.getElementById("tab-1")) {
|
|
455
|
+
document.getElementById("faqs").querySelector("[class='btn btn-primary']").focus();
|
|
456
|
+
} else if (ev.key === "Tab" && !ev.shiftKey && ev.target === document.getElementById("tab-2")) {
|
|
457
|
+
document.getElementById("report-bug").querySelector("[class='btn btn-primary']").focus();
|
|
458
|
+
} else if (ev.key === "Tab" && !ev.shiftKey && ev.target === document.getElementById("tab-3")) {
|
|
459
|
+
document.getElementById("about").querySelector("[href]").focus();
|
|
460
|
+
} else if (ev.key === "Tab" && !ev.shiftKey && ev.target === document.getElementById("tab-4")) {
|
|
461
|
+
const button = document.getElementById("support-modal").getElementsByClassName("modal-footer");
|
|
462
|
+
const close = button[0].firstElementChild;
|
|
463
|
+
close.focus();
|
|
464
|
+
} else if (ev.key === "Enter" || ev.key === "Space" || ev.key === " ") {
|
|
465
|
+
tab.click();
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* @param {Event} ev
|
|
471
|
+
*/
|
|
472
|
+
navigateFAQList(ev) {
|
|
473
|
+
|
|
474
|
+
const el = ev.target.nextElementSibling;
|
|
475
|
+
if (ev.key === "Enter" || ev.key === "Space" || ev.key === " ") {
|
|
476
|
+
ev.preventDefault();
|
|
477
|
+
const question = el.classList;
|
|
478
|
+
if (question !== undefined && question.value) {
|
|
479
|
+
if (!question.value.includes("show")) {
|
|
480
|
+
question.add("show");
|
|
481
|
+
} else if (question.contains("show")) {
|
|
482
|
+
question.remove("show");
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
406
488
|
/**
|
|
407
489
|
* Shows the stale indicator to show that the input or recipe has changed
|
|
408
490
|
* since the last bake.
|
|
@@ -153,16 +153,22 @@ class InputWaiter {
|
|
|
153
153
|
paste(event, view) {
|
|
154
154
|
const clipboardData = event.clipboardData;
|
|
155
155
|
const items = clipboardData.items;
|
|
156
|
-
|
|
156
|
+
let files = [];
|
|
157
157
|
for (let i = 0; i < items.length; i++) {
|
|
158
158
|
const item = items[i];
|
|
159
|
-
if (item.kind === "
|
|
160
|
-
|
|
161
|
-
files.
|
|
162
|
-
|
|
163
|
-
|
|
159
|
+
if (item.kind === "string") {
|
|
160
|
+
// If there are any string items they should be preferred over
|
|
161
|
+
// files.
|
|
162
|
+
files = [];
|
|
163
|
+
break;
|
|
164
|
+
} else if (item.kind === "file") {
|
|
165
|
+
files.push(item.getAsFile());
|
|
164
166
|
}
|
|
165
167
|
}
|
|
168
|
+
if (files.length > 0) {
|
|
169
|
+
// Prevent the default paste behavior, afterPaste will load the files instead
|
|
170
|
+
event.preventDefault();
|
|
171
|
+
}
|
|
166
172
|
setTimeout(() => {
|
|
167
173
|
self.afterPaste(files);
|
|
168
174
|
});
|
|
@@ -417,6 +417,8 @@ class RecipeWaiter {
|
|
|
417
417
|
el.classList.add("flow-control-op");
|
|
418
418
|
}
|
|
419
419
|
|
|
420
|
+
$(el).find("[data-toggle='tooltip']").tooltip();
|
|
421
|
+
|
|
420
422
|
// Disable auto-bake if this is a manual op
|
|
421
423
|
if (op.manualBake && this.app.autoBake_) {
|
|
422
424
|
this.manager.controls.setAutoBake(false);
|
|
@@ -442,8 +444,6 @@ class RecipeWaiter {
|
|
|
442
444
|
this.buildRecipeOperation(item);
|
|
443
445
|
document.getElementById("rec-list").appendChild(item);
|
|
444
446
|
|
|
445
|
-
$(item).find("[data-toggle='tooltip']").tooltip();
|
|
446
|
-
|
|
447
447
|
item.dispatchEvent(this.manager.operationadd);
|
|
448
448
|
return item;
|
|
449
449
|
}
|
package/tests/browser/02_ops.js
CHANGED
|
@@ -34,7 +34,14 @@ module.exports = {
|
|
|
34
34
|
testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]);
|
|
35
35
|
testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]);
|
|
36
36
|
testOp(browser, "Add line numbers", "test input", "1 test input");
|
|
37
|
-
testOp(browser, ["From Hex", "Add Text To Image", "
|
|
37
|
+
testOp(browser, ["From Hex", "Add Text To Image", "SHA2"], Images.PNG_HEX, "50cdf8ea483c55564a091650c2bccb4586f919b721e5fe9d6a61660505b4346d6ebdb2ef0cf075a7728cd84cb26ea3e477b5bd86a94a49a27d79423994afb60a", [[], ["Chef", "Center", "Middle", 0, 0, 16, "Roboto"], []]);
|
|
38
|
+
testOp(browser, ["From Hex", "Add Text To Image", "SHA2"], Images.PNG_HEX, "78b3055463d9167dd039e47f451acaf06c593d209f8e405b4e18011cdcf190dc0af5952be887d93c0ebd38738e978120c1294c71104e6b00d3f9de8d6320ec1c", [[], ["Chef", "Center", "Middle", 0, 0, 16, "Roboto Black"], []]);
|
|
39
|
+
testOp(browser, ["From Hex", "Add Text To Image", "SHA2"], Images.PNG_HEX, "4ab4d4b6cb22ad700f6cd144c2c8ecad2a094f21a1d1d5d48eb6c8f97417192f89b4512f6a78276d49668ebef5e89c3a4d14860cb79399a0dafce98c92209e07", [[], ["Chef", "Center", "Middle", 0, 0, 16, "Roboto Mono"], []]);
|
|
40
|
+
testOp(browser, ["From Hex", "Add Text To Image", "SHA2"], Images.PNG_HEX, "11490db4907516b4d9e256da1ac0b02b561fa7547971e6316a8a0b90c9c66585a11f3145672c6d972b1a221d3bfad9c8a97de7ff77fd9442ebc40f39c1ef9ef7", [[], ["Chef", "Center", "Middle", 0, 0, 16, "Roboto Slab"], []]);
|
|
41
|
+
testOp(browser, ["From Hex", "Dither Image", "SHA2"], Images.PNG_HEX, "cbf587a78915cfb14546ba83080b13e5054800802488dd0cb786b8951e7dc0b48f055260917bd0ccfc075e422b9d6aff112948562653995d74e70f0b66367ac3", [[], [], []]);
|
|
42
|
+
testOp(browser, ["From Hex", "Generate Image", "SHA2"], Images.PNG_HEX, "2c451762a6c9192fd31dc80765eab3f447be70ea51f6fdb6911ade4d89d4a98bd0a1ff00b08d76aac472faeceb54b66092e3f3be7bbf899bf3e55ca9c96a56aa", [[], [], []]);
|
|
43
|
+
testOp(browser, ["From Hex", "Image Hue/Saturation/Lightness", "SHA2"], Images.PNG_HEX, "522dfc0bbef00e05c5d6861a002039fa2952e4bbb7fe8d21d0d538ef6f9d65da82065929b4150dc5b8b49460ee6c9bef7f660b86f8d4e7442a07c61c0a152a4b", [[], [50, 50, 50], []]);
|
|
44
|
+
testOp(browser, ["From Hex", "Resize Image", "SHA2"], Images.PNG_HEX, "654bfbf0a0537c901459c4bc22c5fb0bacbf01af775a0733e3a1c46cda5b699bcc4ed85322d813c7bb9b245d62d64425c0766fe03d3d20bc63634e2a4df17626", [[], [64, 64], []]);
|
|
38
45
|
testOp(browser, "Adler-32 Checksum", "test input", "16160411");
|
|
39
46
|
testOp(browser, "Affine Cipher Decode", "test input", "rcqr glnsr", [1, 2]);
|
|
40
47
|
testOp(browser, "Affine Cipher Encode", "test input", "gndg zoujg", [3, 1]);
|
|
@@ -43,6 +50,14 @@ module.exports = {
|
|
|
43
50
|
testOp(browser, "Analyse hash", "0123456789abcdef", /CRC-64/);
|
|
44
51
|
testOp(browser, "Atbash Cipher", "test input", "gvhg rmkfg");
|
|
45
52
|
// testOp(browser, "Avro to JSON", "test input", "test_output");
|
|
53
|
+
testOp(browser,
|
|
54
|
+
[
|
|
55
|
+
"From Hex", "Avro to JSON"
|
|
56
|
+
],
|
|
57
|
+
"4f626a0104166176726f2e736368656d6196017b2274797065223a227265636f7264222c226e616d65223a22736d616c6c222c226669656c6473223a5b7b226e616d65223a226e616d65222c2274797065223a22737472696e67227d5d7d146176726f2e636f646563086e756c6c004e0247632e3702e5b75cdab9a62f1541020e0c6d796e616d654e0247632e3702e5b75cdab9a62f1541",
|
|
58
|
+
'{"name":"myname"}\n',
|
|
59
|
+
[[], [false]]
|
|
60
|
+
);
|
|
46
61
|
testOp(browser, "BLAKE2b", "test input", "33ebdc8f38177f3f3f334eeb117a84e11f061bbca4db6b8923e5cec85103f59f415551a5d5a933fdb6305dc7bf84671c2540b463dbfa08ee1895cfaa5bd780b5", ["512", "Hex", { "option": "UTF8", "string": "pass" }]);
|
|
47
62
|
testOp(browser, "BLAKE2s", "test input", "defe73d61dfa6e5807e4f9643e159a09ccda6be3c26dcd65f8a9bb38bfc973a7", ["256", "Hex", { "option": "UTF8", "string": "pass" }]);
|
|
48
63
|
testOp(browser, "BSON deserialise", "\u0011\u0000\u0000\u0000\u0002a\u0000\u0005\u0000\u0000\u0000test\u0000\u0000", '{\u000A "a": "test"\u000A}');
|
|
@@ -58,7 +73,10 @@ module.exports = {
|
|
|
58
73
|
testOp(browser, "Bit shift right", "test input", ":29:\u0010478::");
|
|
59
74
|
testOp(browser, "Blowfish Decrypt", "10884e15427dd84ec35204e9c8e921ae", "test_output", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Hex", "Raw"]);
|
|
60
75
|
testOp(browser, "Blowfish Encrypt", "test input", "f0fadbd1d90d774f714248cf26b96410", [{"option": "Hex", "string": "1234567801234567"}, {"option": "Hex", "string": "0011223344556677"}, "CBC", "Raw", "Hex"]);
|
|
61
|
-
testOp(browser, ["From Hex", "Blur Image", "
|
|
76
|
+
testOp(browser, ["From Hex", "Blur Image", "SHA2"], Images.PNG_HEX, "24f2e89f3e00cc35f551bbc48ea82e76474946ce0282183494d1ca3d3b0012c27b6102c4368ae056dc7fecb6df7886d86ff3d29b7e5965493f30c371eee9a24e");
|
|
77
|
+
testOp(browser, ["From Hex", "Blur Image", "SHA2"], Images.PNG_HEX, "2c49d89fc10c94352c9a19f82de353c37928831d6f976a6b36eb918825a0ba027980801838228a4a0da63f1886e4fa59b6666f992ad2d2b7d4622253dc034052", [[], [5, "Gaussian"], []]);
|
|
78
|
+
testOp(browser, ["From Hex", "Sharpen Image", "SHA2"], Images.PNG_HEX, "acc7027642c2eeb67d7356a80ed8a1bdce9adabf656ea1294e47723f506626a7aa41f1660fa844a1e1e83b17180017ab0d5bccd7f6a341692832020dc887eaa5");
|
|
79
|
+
testOp(browser, ["From Hex", "Contain Image", "SHA2"], Images.PNG_HEX, "cb871ad0722d487d56a2b18247b1aa30ecc244eb717e08e23a55cae78759553312dc1717196d7cb9daa04743e57c56fc3901ba92be5a68fb03c377f718e8efe7");
|
|
62
80
|
testOpHtml(browser, "Bombe", "XTSYN WAEUG EZALY NRQIM AMLZX MFUOD AWXLY LZCUZ QOQBQ JLCPK NDDRW F", "table tr:last-child td:first-child", "ECG", ["3-rotor", "LEYJVCNIXWPBQMDRTAKZGFUHOS", "BDFHJLCPRTXVZNYEIWGAKMUSQO<W", "AJDKSIRUXBLHWTMCQGZNPYFVOE<F", "ESOVPZJAYQUIRHXLNFTGKDCMWB<K", "AY BR CU DH EQ FS GL IP JX KN MO TZ VW", "HELLO CYBER CHEFU SER", 0, true]);
|
|
63
81
|
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");
|
|
64
82
|
testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [[], [true]]);
|
|
@@ -196,6 +214,7 @@ module.exports = {
|
|
|
196
214
|
testOpHtml(browser, "Index of Coincidence", "test input", "", /Index of Coincidence: 0.08333333333333333/);
|
|
197
215
|
testOpImage(browser, "Invert Image", "files/Hitchhikers_Guide.jpeg");
|
|
198
216
|
// testOp(browser, "JPath expression", "test input", "test_output");
|
|
217
|
+
testOp(browser, "Jq", '{"a":{"b":1}}', '{"b":1}', [".a"]);
|
|
199
218
|
testOpHtml(browser, "JSON Beautify", "{a:1}", ".json-dict .json-literal", "1");
|
|
200
219
|
// testOp(browser, "JSON Minify", "test input", "test_output");
|
|
201
220
|
// testOp(browser, "JSON to CSV", "test input", "test_output");
|
|
@@ -249,7 +268,7 @@ module.exports = {
|
|
|
249
268
|
testOpHtml(browser, "Parse colour code", "#000", ".colorpicker-preview", "rgb(0, 0, 0)");
|
|
250
269
|
testOpHtml(browser, "Parse DateTime", "01/12/2000 13:00:00", "", /Date: Friday 1st December 2000/);
|
|
251
270
|
// testOp(browser, "Parse IP range", "test input", "test_output");
|
|
252
|
-
testOpHtml(browser, "Parse IPv4 header", "45 c0 00 c4 02 89 00 00 ff 11 1e 8c c0 a8 0c 01 c0 a8 0c 02", "tr:last-child td:last-child", "192.168.12.2");
|
|
271
|
+
testOpHtml(browser, "Parse IPv4 header", "45 c0 00 c4 02 89 00 00 ff 11 1e 8c c0 a8 0c 01 c0 a8 0c 02", "tr:nth-last-child(2) td:last-child", "192.168.12.2");
|
|
253
272
|
// testOp(browser, "Parse IPv6 address", "test input", "test_output");
|
|
254
273
|
// testOp(browser, "Parse ObjectID timestamp", "test input", "test_output");
|
|
255
274
|
// testOp(browser, "Parse QR Code", "test input", "test_output");
|
|
@@ -335,6 +354,7 @@ module.exports = {
|
|
|
335
354
|
// testOp(browser, "Tail", "test input", "test_output");
|
|
336
355
|
// testOp(browser, "Take bytes", "test input", "test_output");
|
|
337
356
|
testOp(browser, "Tar", "test input", /^file\.txt\x00{92}/);
|
|
357
|
+
testOp(browser, "Template", "{\"one\": 1, \"two\": 2}", "1 2", ["{{ one }} {{ two }}"]);
|
|
338
358
|
testOpHtml(browser, "Text Encoding Brute Force", "test input", "tr:nth-of-type(4) td:last-child", /t\u2400e\u2400s\u2400t\u2400/);
|
|
339
359
|
// testOp(browser, "To BCD", "test input", "test_output");
|
|
340
360
|
// testOp(browser, "To Base", "test input", "test_output");
|
package/tests/node/index.mjs
CHANGED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import TestRegister from "../../../lib/TestRegister.mjs";
|
|
2
|
+
import { parseBigInt, egcd, modPow } from "../../../../src/core/lib/BigIntUtils.mjs";
|
|
3
|
+
import it from "../../assertionHandler.mjs";
|
|
4
|
+
import assert from "assert";
|
|
5
|
+
|
|
6
|
+
TestRegister.addApiTests([
|
|
7
|
+
// ===== parseBigInt tests =====
|
|
8
|
+
it("BigIntUtils: parseBigInt - decimal number", () => {
|
|
9
|
+
const value = parseBigInt("1", "test value");
|
|
10
|
+
assert.deepStrictEqual(value, BigInt("1"));
|
|
11
|
+
}),
|
|
12
|
+
|
|
13
|
+
it("BigIntUtils: parseBigInt - large decimal", () => {
|
|
14
|
+
const value = parseBigInt("123456789012345678901234567890", "test value");
|
|
15
|
+
assert.deepStrictEqual(value, BigInt("123456789012345678901234567890"));
|
|
16
|
+
}),
|
|
17
|
+
|
|
18
|
+
it("BigIntUtils: parseBigInt - hexadecimal lowercase", () => {
|
|
19
|
+
const value = parseBigInt("0xff", "test value");
|
|
20
|
+
assert.deepStrictEqual(value, BigInt("255"));
|
|
21
|
+
}),
|
|
22
|
+
|
|
23
|
+
it("BigIntUtils: parseBigInt - hexadecimal uppercase", () => {
|
|
24
|
+
const value = parseBigInt("0xFF", "test value");
|
|
25
|
+
assert.deepStrictEqual(value, BigInt("255"));
|
|
26
|
+
}),
|
|
27
|
+
|
|
28
|
+
it("BigIntUtils: parseBigInt - large hexadecimal", () => {
|
|
29
|
+
const value = parseBigInt("0x123456789ABCDEF", "test value");
|
|
30
|
+
assert.deepStrictEqual(value, BigInt("0x123456789ABCDEF"));
|
|
31
|
+
}),
|
|
32
|
+
|
|
33
|
+
it("BigIntUtils: parseBigInt - whitespace trimming", () => {
|
|
34
|
+
const value = parseBigInt(" 42 ", "test value");
|
|
35
|
+
assert.deepStrictEqual(value, BigInt("42"));
|
|
36
|
+
}),
|
|
37
|
+
|
|
38
|
+
it("BigIntUtils: parseBigInt - invalid input (text)", () => {
|
|
39
|
+
assert.throws(() => parseBigInt("test", "test value"), {
|
|
40
|
+
name: "Error",
|
|
41
|
+
message: "test value must be decimal or hex (0x...)"
|
|
42
|
+
});
|
|
43
|
+
}),
|
|
44
|
+
|
|
45
|
+
it("BigIntUtils: parseBigInt - invalid input (hex without prefix)", () => {
|
|
46
|
+
assert.throws(() => parseBigInt("FF", "test value"), {
|
|
47
|
+
name: "Error",
|
|
48
|
+
message: "test value must be decimal or hex (0x...)"
|
|
49
|
+
});
|
|
50
|
+
}),
|
|
51
|
+
|
|
52
|
+
it("BigIntUtils: parseBigInt - invalid input (mixed)", () => {
|
|
53
|
+
assert.throws(() => parseBigInt("12abc", "test value"), {
|
|
54
|
+
name: "Error",
|
|
55
|
+
message: "test value must be decimal or hex (0x...)"
|
|
56
|
+
});
|
|
57
|
+
}),
|
|
58
|
+
|
|
59
|
+
// ===== egcd tests =====
|
|
60
|
+
it("BigIntUtils: egcd - basic coprime", () => {
|
|
61
|
+
const a = BigInt("36");
|
|
62
|
+
const b = BigInt("48");
|
|
63
|
+
const gcd = BigInt("12");
|
|
64
|
+
const bezout1 = BigInt("-1");
|
|
65
|
+
const bezout2 = BigInt("1");
|
|
66
|
+
assert.deepStrictEqual(egcd(a, b), [gcd, bezout1, bezout2]);
|
|
67
|
+
}),
|
|
68
|
+
|
|
69
|
+
it("BigIntUtils: egcd - coprime numbers", () => {
|
|
70
|
+
const [g, x, y] = egcd(BigInt("3"), BigInt("11"));
|
|
71
|
+
assert.strictEqual(g, BigInt("1"));
|
|
72
|
+
// Verify Bézout identity: a*x + b*y = gcd
|
|
73
|
+
assert.strictEqual(BigInt("3") * x + BigInt("11") * y, g);
|
|
74
|
+
}),
|
|
75
|
+
|
|
76
|
+
it("BigIntUtils: egcd - non-coprime numbers", () => {
|
|
77
|
+
const [g, x, y] = egcd(BigInt("240"), BigInt("46"));
|
|
78
|
+
assert.strictEqual(g, BigInt("2"));
|
|
79
|
+
// Verify Bézout identity
|
|
80
|
+
assert.strictEqual(BigInt("240") * x + BigInt("46") * y, g);
|
|
81
|
+
}),
|
|
82
|
+
|
|
83
|
+
it("BigIntUtils: egcd - with zero", () => {
|
|
84
|
+
const [g, x, y] = egcd(BigInt("17"), BigInt("0"));
|
|
85
|
+
assert.strictEqual(g, BigInt("17"));
|
|
86
|
+
assert.strictEqual(x, BigInt("1"));
|
|
87
|
+
assert.strictEqual(y, BigInt("0"));
|
|
88
|
+
}),
|
|
89
|
+
|
|
90
|
+
it("BigIntUtils: egcd - identical numbers", () => {
|
|
91
|
+
const [g, x, y] = egcd(BigInt("42"), BigInt("42"));
|
|
92
|
+
assert.strictEqual(g, BigInt("42"));
|
|
93
|
+
// Verify Bézout identity
|
|
94
|
+
assert.strictEqual(BigInt("42") * x + BigInt("42") * y, g);
|
|
95
|
+
}),
|
|
96
|
+
|
|
97
|
+
it("BigIntUtils: egcd - large numbers", () => {
|
|
98
|
+
const a = BigInt("123456789012345678901234567890");
|
|
99
|
+
const b = BigInt("987654321098765432109876543210");
|
|
100
|
+
const [g, x, y] = egcd(a, b);
|
|
101
|
+
// Verify Bézout identity
|
|
102
|
+
assert.strictEqual(a * x + b * y, g);
|
|
103
|
+
}),
|
|
104
|
+
|
|
105
|
+
// ===== modPow tests =====
|
|
106
|
+
it("BigIntUtils: modPow - basic", () => {
|
|
107
|
+
// 2^10 mod 1000 = 1024 mod 1000 = 24
|
|
108
|
+
const result = modPow(BigInt("2"), BigInt("10"), BigInt("1000"));
|
|
109
|
+
assert.strictEqual(result, BigInt("24"));
|
|
110
|
+
}),
|
|
111
|
+
|
|
112
|
+
it("BigIntUtils: modPow - RSA-like example", () => {
|
|
113
|
+
// Common RSA public exponent
|
|
114
|
+
const base = BigInt("123456789");
|
|
115
|
+
const exp = BigInt("65537");
|
|
116
|
+
const mod = BigInt("999999999999");
|
|
117
|
+
const result = modPow(base, exp, mod);
|
|
118
|
+
// Result should be less than modulus
|
|
119
|
+
assert(result < mod);
|
|
120
|
+
assert(result >= BigInt("0"));
|
|
121
|
+
}),
|
|
122
|
+
|
|
123
|
+
it("BigIntUtils: modPow - exponent zero", () => {
|
|
124
|
+
// Any number^0 = 1
|
|
125
|
+
const result = modPow(BigInt("999"), BigInt("0"), BigInt("100"));
|
|
126
|
+
assert.strictEqual(result, BigInt("1"));
|
|
127
|
+
}),
|
|
128
|
+
|
|
129
|
+
it("BigIntUtils: modPow - base zero", () => {
|
|
130
|
+
// 0^n = 0
|
|
131
|
+
const result = modPow(BigInt("0"), BigInt("5"), BigInt("100"));
|
|
132
|
+
assert.strictEqual(result, BigInt("0"));
|
|
133
|
+
}),
|
|
134
|
+
|
|
135
|
+
it("BigIntUtils: modPow - large exponent", () => {
|
|
136
|
+
// Test with very large exponent (efficient algorithm should handle this)
|
|
137
|
+
const result = modPow(BigInt("3"), BigInt("1000000"), BigInt("1000000007"));
|
|
138
|
+
assert(result >= BigInt("0"));
|
|
139
|
+
assert(result < BigInt("1000000007"));
|
|
140
|
+
}),
|
|
141
|
+
|
|
142
|
+
it("BigIntUtils: modPow - modular inverse verification", () => {
|
|
143
|
+
// If a*x . 1 (mod m), then modPow(a, 1, m) * x . 1 (mod m)
|
|
144
|
+
const a = BigInt("3");
|
|
145
|
+
const m = BigInt("11");
|
|
146
|
+
const x = BigInt("4"); // inverse of 3 mod 11
|
|
147
|
+
const result = modPow(a, BigInt("1"), m) * x % m;
|
|
148
|
+
assert.strictEqual(result, BigInt("1"));
|
|
149
|
+
}),
|
|
150
|
+
]);
|
|
@@ -867,13 +867,15 @@ pCGTErs=
|
|
|
867
867
|
}),
|
|
868
868
|
|
|
869
869
|
it("SQL Beautify", () => {
|
|
870
|
-
const result = chef.SQLBeautify(`SELECT MONTH, ID, RAIN_I, TEMP_F
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
870
|
+
const result = chef.SQLBeautify(`SELECT MONTH, ID, RAIN_I, TEMP_F FROM STATS;`);
|
|
871
|
+
const expected =
|
|
872
|
+
`SELECT
|
|
873
|
+
MONTH,
|
|
874
|
+
ID,
|
|
875
|
+
RAIN_I,
|
|
876
|
+
TEMP_F
|
|
877
|
+
FROM
|
|
878
|
+
STATS;`;
|
|
877
879
|
assert.strictEqual(result.toString(), expected);
|
|
878
880
|
}),
|
|
879
881
|
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { setLongTestFailure, logTestReport } from "../lib/utils.mjs";
|
|
15
15
|
|
|
16
16
|
import TestRegister from "../lib/TestRegister.mjs";
|
|
17
|
+
import "./tests/A1Z26CipherDecode.mjs";
|
|
17
18
|
import "./tests/AESKeyWrap.mjs";
|
|
18
19
|
import "./tests/AlternatingCaps.mjs";
|
|
19
20
|
import "./tests/AvroToJSON.mjs";
|
|
@@ -61,10 +62,12 @@ import "./tests/Crypt.mjs";
|
|
|
61
62
|
import "./tests/CSV.mjs";
|
|
62
63
|
import "./tests/DateTime.mjs";
|
|
63
64
|
import "./tests/DefangIP.mjs";
|
|
65
|
+
import "./tests/DisassembleARM.mjs";
|
|
64
66
|
import "./tests/DropNthBytes.mjs";
|
|
65
67
|
import "./tests/ECDSA.mjs";
|
|
66
68
|
import "./tests/ELFInfo.mjs";
|
|
67
69
|
import "./tests/Enigma.mjs";
|
|
70
|
+
import "./tests/ExtractAudioMetadata.mjs";
|
|
68
71
|
import "./tests/ExtractEmailAddresses.mjs";
|
|
69
72
|
import "./tests/ExtractHashes.mjs";
|
|
70
73
|
import "./tests/ExtractIPAddresses.mjs";
|
|
@@ -76,6 +79,7 @@ import "./tests/FromDecimal.mjs";
|
|
|
76
79
|
import "./tests/GenerateAllChecksums.mjs";
|
|
77
80
|
import "./tests/GenerateAllHashes.mjs";
|
|
78
81
|
import "./tests/GenerateDeBruijnSequence.mjs";
|
|
82
|
+
import "./tests/GenerateQRCode.mjs";
|
|
79
83
|
import "./tests/GetAllCasings.mjs";
|
|
80
84
|
import "./tests/GOST.mjs";
|
|
81
85
|
import "./tests/Gunzip.mjs";
|
|
@@ -118,6 +122,7 @@ import "./tests/NetBIOS.mjs";
|
|
|
118
122
|
import "./tests/NormaliseUnicode.mjs";
|
|
119
123
|
import "./tests/NTLM.mjs";
|
|
120
124
|
import "./tests/OTP.mjs";
|
|
125
|
+
import "./tests/ParseEthernetFrame.mjs";
|
|
121
126
|
import "./tests/ParseIPRange.mjs";
|
|
122
127
|
import "./tests/ParseObjectIDTimestamp.mjs";
|
|
123
128
|
import "./tests/ParseQRCode.mjs";
|
|
@@ -151,7 +156,9 @@ import "./tests/Shuffle.mjs";
|
|
|
151
156
|
import "./tests/SIGABA.mjs";
|
|
152
157
|
import "./tests/SM2.mjs";
|
|
153
158
|
import "./tests/SM4.mjs";
|
|
159
|
+
import "./tests/RC6.mjs";
|
|
154
160
|
// import "./tests/SplitColourChannels.mjs"; // Cannot test operations that use the File type yet
|
|
161
|
+
import "./tests/SQLBeautify.mjs";
|
|
155
162
|
import "./tests/StrUtils.mjs";
|
|
156
163
|
import "./tests/StripIPv4Header.mjs";
|
|
157
164
|
import "./tests/StripTCPHeader.mjs";
|
|
@@ -162,6 +169,7 @@ import "./tests/SymmetricDifference.mjs";
|
|
|
162
169
|
import "./tests/TakeNthBytes.mjs";
|
|
163
170
|
import "./tests/Template.mjs";
|
|
164
171
|
import "./tests/TextEncodingBruteForce.mjs";
|
|
172
|
+
import "./tests/TextIntegerConverter.mjs";
|
|
165
173
|
import "./tests/ToFromInsensitiveRegex.mjs";
|
|
166
174
|
import "./tests/TranslateDateTimeFormat.mjs";
|
|
167
175
|
import "./tests/Typex.mjs";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A1Z26 Cipher Decode tests
|
|
3
|
+
*
|
|
4
|
+
* @author brick-pixel
|
|
5
|
+
* @copyright Crown Copyright 2026
|
|
6
|
+
* @license Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
9
|
+
|
|
10
|
+
TestRegister.addTests([
|
|
11
|
+
{
|
|
12
|
+
"name": "A1Z26 Cipher Decode: basic decode",
|
|
13
|
+
"input": "8 5 12 12 15",
|
|
14
|
+
"expectedOutput": "hello",
|
|
15
|
+
"recipeConfig": [
|
|
16
|
+
{
|
|
17
|
+
"op": "A1Z26 Cipher Decode",
|
|
18
|
+
"args": ["Space"]
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "A1Z26 Cipher Decode: empty input returns empty string",
|
|
24
|
+
"input": "",
|
|
25
|
+
"expectedOutput": "",
|
|
26
|
+
"recipeConfig": [
|
|
27
|
+
{
|
|
28
|
+
"op": "A1Z26 Cipher Decode",
|
|
29
|
+
"args": ["Space"]
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
]);
|