cyberchef 10.23.0 → 10.24.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 +51 -0
- package/CONTRIBUTING.md +4 -1
- package/Gruntfile.js +2 -16
- package/package.json +14 -14
- package/src/core/config/Categories.json +2 -1
- package/src/core/config/OperationConfig.json +54 -3
- package/src/core/config/modules/Default.mjs +2 -0
- package/src/core/config/scripts/fixCryptoApiImports.mjs +54 -0
- package/src/core/config/scripts/fixSnackBarMarkup.mjs +28 -0
- package/src/core/lib/Extract.mjs +5 -0
- package/src/core/lib/ParityBit.mjs +50 -0
- package/src/core/operations/AnalyseUUID.mjs +109 -6
- package/src/core/operations/ExtractEmailAddresses.mjs +2 -3
- package/src/core/operations/ParityBit.mjs +128 -0
- package/src/core/operations/RegularExpression.mjs +2 -1
- package/src/core/operations/RenderMarkdown.mjs +35 -4
- package/src/core/operations/index.mjs +2 -0
- package/src/node/index.mjs +5 -0
- package/src/web/HTMLOperation.mjs +8 -2
- package/src/web/html/index.html +1 -1
- package/src/web/waiters/OperationsWaiter.mjs +30 -13
- package/tests/node/tests/operations.mjs +2 -3
- package/tests/operations/index.mjs +5 -0
- package/tests/operations/tests/AnalyseUUID.mjs +66 -0
- package/tests/operations/tests/ExtractEmailAddresses.mjs +38 -12
- package/tests/operations/tests/Fernet.mjs +18 -3
- package/tests/operations/tests/ParityBit.mjs +147 -0
- package/tests/operations/tests/RegularExpression.mjs +75 -0
- package/tests/operations/tests/RenderMarkdown.mjs +110 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author j83305 [awz22@protonmail.com]
|
|
3
|
+
* @copyright Crown Copyright 2020
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
import { calculateParityBit, decodeParityBit } from "../lib/ParityBit.mjs";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Parity Bit operation
|
|
12
|
+
*/
|
|
13
|
+
class ParityBit extends Operation {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* ParityBit constructor
|
|
17
|
+
*/
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
|
|
21
|
+
this.name = "Parity Bit";
|
|
22
|
+
this.module = "Default";
|
|
23
|
+
this.description = "A parity bit, or check bit, is the simplest form of error detection. It is a bit which is added to a string of bits and represents if the number of 1's in the binary string is an even number or odd number.<br><br>If a delimiter is specified, the parity bit calculation will be performed on each 'block' of the input data, where the blocks are created by slicing the input at each occurence of the delimiter character";
|
|
24
|
+
this.infoURL = "https://wikipedia.org/wiki/Parity_bit";
|
|
25
|
+
this.inputType = "string";
|
|
26
|
+
this.outputType = "string";
|
|
27
|
+
this.args = [
|
|
28
|
+
{
|
|
29
|
+
name: "Mode",
|
|
30
|
+
type: "option",
|
|
31
|
+
value: [
|
|
32
|
+
"Even Parity",
|
|
33
|
+
"Odd Parity"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "Postion",
|
|
38
|
+
type: "option",
|
|
39
|
+
value: [
|
|
40
|
+
"Start",
|
|
41
|
+
"End"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "Encode or Decode",
|
|
46
|
+
type: "option",
|
|
47
|
+
value: [
|
|
48
|
+
"Encode",
|
|
49
|
+
"Decode"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "Delimiter",
|
|
54
|
+
type: "shortString",
|
|
55
|
+
value: ""
|
|
56
|
+
}
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {string} input
|
|
62
|
+
* @param {Object[]} args
|
|
63
|
+
* @returns {string}
|
|
64
|
+
*/
|
|
65
|
+
run(input, args) {
|
|
66
|
+
if (input.length === 0) {
|
|
67
|
+
return input;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* determines weather to use the encode or decode method based off args[2]
|
|
71
|
+
* @param input input to be encoded or decoded
|
|
72
|
+
* @param args array
|
|
73
|
+
*/
|
|
74
|
+
const method = (input, args) => args[2] === "Encode" ? calculateParityBit(input, args) : decodeParityBit(input, args);
|
|
75
|
+
if (args[3].length > 0) {
|
|
76
|
+
const byteStrings = input.split(args[3]);
|
|
77
|
+
for (let byteStringsArrayIndex = 0; byteStringsArrayIndex < byteStrings.length; byteStringsArrayIndex++) {
|
|
78
|
+
byteStrings[byteStringsArrayIndex] = method(byteStrings[byteStringsArrayIndex], args);
|
|
79
|
+
}
|
|
80
|
+
return byteStrings.join(args[3]);
|
|
81
|
+
}
|
|
82
|
+
return method(input, args);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Highlight Parity Bit
|
|
87
|
+
*
|
|
88
|
+
* @param {Object[]} pos
|
|
89
|
+
* @param {number} pos[].start
|
|
90
|
+
* @param {number} pos[].end
|
|
91
|
+
* @param {Object[]} args
|
|
92
|
+
* @returns {Object[]} pos
|
|
93
|
+
*/
|
|
94
|
+
highlight(pos, args) {
|
|
95
|
+
if (args[3].length === 0) {
|
|
96
|
+
if (args[1] === "Prepend") {
|
|
97
|
+
pos[0].start += 1;
|
|
98
|
+
pos[0].end += 1;
|
|
99
|
+
}
|
|
100
|
+
return pos;
|
|
101
|
+
}
|
|
102
|
+
// need to be able to read input to do the highlighting when there is a delimiter
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Highlight Parity Bit in reverse
|
|
107
|
+
*
|
|
108
|
+
* @param {Object[]} pos
|
|
109
|
+
* @param {number} pos[].start
|
|
110
|
+
* @param {number} pos[].end
|
|
111
|
+
* @param {Object[]} args
|
|
112
|
+
* @returns {Object[]} pos
|
|
113
|
+
*/
|
|
114
|
+
highlightReverse(pos, args) {
|
|
115
|
+
if (args[3].length === 0) {
|
|
116
|
+
if (args[1] === "Prepend") {
|
|
117
|
+
if (pos[0].start > 0) {
|
|
118
|
+
pos[0].start -= 1;
|
|
119
|
+
}
|
|
120
|
+
pos[0].end -= 1;
|
|
121
|
+
}
|
|
122
|
+
return pos;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export default ParityBit;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import XRegExp from "xregexp";
|
|
8
8
|
import Operation from "../Operation.mjs";
|
|
9
9
|
import Utils from "../Utils.mjs";
|
|
10
|
+
import { EMAIL_REGEX } from "../lib/Extract.mjs";
|
|
10
11
|
import OperationError from "../errors/OperationError.mjs";
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -45,7 +46,7 @@ class RegularExpression extends Operation {
|
|
|
45
46
|
},
|
|
46
47
|
{
|
|
47
48
|
name: "Email address",
|
|
48
|
-
value:
|
|
49
|
+
value: EMAIL_REGEX.source // We use a different regex library, so just take the source regex string here
|
|
49
50
|
},
|
|
50
51
|
{
|
|
51
52
|
name: "URL",
|
|
@@ -35,6 +35,11 @@ class RenderMarkdown extends Operation {
|
|
|
35
35
|
name: "Enable syntax highlighting",
|
|
36
36
|
type: "boolean",
|
|
37
37
|
value: true
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "Open links in new tab.",
|
|
41
|
+
type: "boolean",
|
|
42
|
+
value: false
|
|
38
43
|
}
|
|
39
44
|
];
|
|
40
45
|
}
|
|
@@ -45,7 +50,7 @@ class RenderMarkdown extends Operation {
|
|
|
45
50
|
* @returns {html}
|
|
46
51
|
*/
|
|
47
52
|
run(input, args) {
|
|
48
|
-
const [convertLinks, enableHighlighting] = args,
|
|
53
|
+
const [convertLinks, enableHighlighting, openLinksBlank] = args,
|
|
49
54
|
md = new MarkdownIt({
|
|
50
55
|
linkify: convertLinks,
|
|
51
56
|
html: false, // Explicitly disable HTML rendering
|
|
@@ -58,12 +63,38 @@ class RenderMarkdown extends Operation {
|
|
|
58
63
|
|
|
59
64
|
return "";
|
|
60
65
|
}
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
});
|
|
67
|
+
if (openLinksBlank) {
|
|
68
|
+
this.makeLinksOpenInNewTab(md);
|
|
69
|
+
}
|
|
70
|
+
const rendered = md.render(input);
|
|
64
71
|
return `<div style="font-family: var(--primary-font-family)">${rendered}</div>`;
|
|
65
72
|
}
|
|
66
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Adds target="_blank" to links.
|
|
76
|
+
* @param {MarkdownIt} md
|
|
77
|
+
*/
|
|
78
|
+
makeLinksOpenInNewTab(md) {
|
|
79
|
+
// Adapted from: https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer
|
|
80
|
+
// Remember old renderer, if overridden, or proxy to default renderer
|
|
81
|
+
const defaultRender = md.renderer.rules.link_open || function(tokens, idx, options, env, self) {
|
|
82
|
+
return self.renderToken(tokens, idx, options);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// eslint-disable-next-line camelcase
|
|
86
|
+
md.renderer.rules.link_open = function (tokens, idx, options, env, self) {
|
|
87
|
+
const token = tokens[idx];
|
|
88
|
+
if (token.attrIndex("target") >= 0) {
|
|
89
|
+
// Target attribute already set, do not replace.
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
token.attrPush(["target", "_blank"]); // add new attribute
|
|
93
|
+
|
|
94
|
+
// pass token to default renderer.
|
|
95
|
+
return defaultRender(tokens, idx, options, env, self);
|
|
96
|
+
};
|
|
97
|
+
}
|
|
67
98
|
}
|
|
68
99
|
|
|
69
100
|
export default RenderMarkdown;
|
|
@@ -288,6 +288,7 @@ import PHPDeserialize from "./PHPDeserialize.mjs";
|
|
|
288
288
|
import PHPSerialize from "./PHPSerialize.mjs";
|
|
289
289
|
import PLISTViewer from "./PLISTViewer.mjs";
|
|
290
290
|
import PadLines from "./PadLines.mjs";
|
|
291
|
+
import ParityBit from "./ParityBit.mjs";
|
|
291
292
|
import ParseASN1HexString from "./ParseASN1HexString.mjs";
|
|
292
293
|
import ParseCSR from "./ParseCSR.mjs";
|
|
293
294
|
import ParseColourCode from "./ParseColourCode.mjs";
|
|
@@ -765,6 +766,7 @@ export {
|
|
|
765
766
|
PHPSerialize,
|
|
766
767
|
PLISTViewer,
|
|
767
768
|
PadLines,
|
|
769
|
+
ParityBit,
|
|
768
770
|
ParseASN1HexString,
|
|
769
771
|
ParseCSR,
|
|
770
772
|
ParseColourCode,
|
package/src/node/index.mjs
CHANGED
|
@@ -289,6 +289,7 @@ import {
|
|
|
289
289
|
PHPSerialize as core_PHPSerialize,
|
|
290
290
|
PLISTViewer as core_PLISTViewer,
|
|
291
291
|
PadLines as core_PadLines,
|
|
292
|
+
ParityBit as core_ParityBit,
|
|
292
293
|
ParseASN1HexString as core_ParseASN1HexString,
|
|
293
294
|
ParseCSR as core_ParseCSR,
|
|
294
295
|
ParseColourCode as core_ParseColourCode,
|
|
@@ -766,6 +767,7 @@ function generateChef() {
|
|
|
766
767
|
"PHPSerialize": _wrap(core_PHPSerialize),
|
|
767
768
|
"PLISTViewer": _wrap(core_PLISTViewer),
|
|
768
769
|
"padLines": _wrap(core_PadLines),
|
|
770
|
+
"parityBit": _wrap(core_ParityBit),
|
|
769
771
|
"parseASN1HexString": _wrap(core_ParseASN1HexString),
|
|
770
772
|
"parseCSR": _wrap(core_ParseCSR),
|
|
771
773
|
"parseColourCode": _wrap(core_ParseColourCode),
|
|
@@ -1260,6 +1262,7 @@ const PHPDeserialize = chef.PHPDeserialize;
|
|
|
1260
1262
|
const PHPSerialize = chef.PHPSerialize;
|
|
1261
1263
|
const PLISTViewer = chef.PLISTViewer;
|
|
1262
1264
|
const padLines = chef.padLines;
|
|
1265
|
+
const parityBit = chef.parityBit;
|
|
1263
1266
|
const parseASN1HexString = chef.parseASN1HexString;
|
|
1264
1267
|
const parseCSR = chef.parseCSR;
|
|
1265
1268
|
const parseColourCode = chef.parseColourCode;
|
|
@@ -1739,6 +1742,7 @@ const operations = [
|
|
|
1739
1742
|
PHPSerialize,
|
|
1740
1743
|
PLISTViewer,
|
|
1741
1744
|
padLines,
|
|
1745
|
+
parityBit,
|
|
1742
1746
|
parseASN1HexString,
|
|
1743
1747
|
parseCSR,
|
|
1744
1748
|
parseColourCode,
|
|
@@ -2222,6 +2226,7 @@ export {
|
|
|
2222
2226
|
PHPSerialize,
|
|
2223
2227
|
PLISTViewer,
|
|
2224
2228
|
padLines,
|
|
2229
|
+
parityBit,
|
|
2225
2230
|
parseASN1HexString,
|
|
2226
2231
|
parseCSR,
|
|
2227
2232
|
parseColourCode,
|
|
@@ -43,17 +43,23 @@ class HTMLOperation {
|
|
|
43
43
|
/**
|
|
44
44
|
* Renders the operation in HTML as a stub operation with no ingredients.
|
|
45
45
|
*
|
|
46
|
+
* @param {boolean} removeIcon - show icon for removing operation
|
|
47
|
+
* @param {string} elementId - element ID for aria usage
|
|
46
48
|
* @returns {string}
|
|
47
49
|
*/
|
|
48
|
-
toStubHtml(removeIcon) {
|
|
50
|
+
toStubHtml(removeIcon = false, elementId = null) {
|
|
49
51
|
let html = "<li class='operation'";
|
|
50
52
|
|
|
53
|
+
if (elementId) {
|
|
54
|
+
html += ` id='${elementId}'`;
|
|
55
|
+
}
|
|
56
|
+
|
|
51
57
|
if (this.description) {
|
|
52
58
|
const infoLink = this.infoURL ? `<hr>${titleFromWikiLink(this.infoURL)}` : "";
|
|
53
59
|
|
|
54
60
|
html += ` data-container='body' data-toggle='popover' data-placement='right'
|
|
55
61
|
data-content="${this.description}${infoLink}" data-html='true' data-trigger='hover'
|
|
56
|
-
data-boundary='viewport'`;
|
|
62
|
+
data-boundary='viewport' role='button'`;
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
html += ">" + this.name;
|
package/src/web/html/index.html
CHANGED
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
Operations
|
|
174
174
|
<span class="op-count"></span>
|
|
175
175
|
</div>
|
|
176
|
-
<input id="search" type="search" class="form-control" placeholder="Search..." autocomplete="off" tabindex="0" data-help-title="Searching for operations" data-help="<p>Use the search box to find useful operations.</p><p>Both operation names and descriptions are queried using a fuzzy matching algorithm.</p>">
|
|
176
|
+
<input id="search" type="search" class="form-control" placeholder="Search..." autocomplete="off" tabindex="0" data-help-title="Searching for operations" data-help="<p>Use the search box to find useful operations.</p><p>Both operation names and descriptions are queried using a fuzzy matching algorithm.</p>" aria-owns="search-results">
|
|
177
177
|
<ul id="search-results" class="op-list"></ul>
|
|
178
178
|
<div id="categories" class="panel-group no-select"></div>
|
|
179
179
|
</div>
|
|
@@ -28,17 +28,16 @@ class OperationsWaiter {
|
|
|
28
28
|
this.removeIntent = false;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
32
31
|
/**
|
|
33
32
|
* Handler for search events.
|
|
34
33
|
* Finds operations which match the given search term and displays them under the search box.
|
|
35
34
|
*
|
|
36
|
-
* @param {
|
|
35
|
+
* @param {KeyboardEvent | ClipboardEvent | Event} e
|
|
37
36
|
*/
|
|
38
37
|
searchOperations(e) {
|
|
39
38
|
let ops, selected;
|
|
40
39
|
|
|
41
|
-
if (e.type === "search" || e.keyCode === 13) { // Search or Return
|
|
40
|
+
if ((e.type === "search" && e.target.value !== "") || e.keyCode === 13) { // Search (non-empty) or Return
|
|
42
41
|
e.preventDefault();
|
|
43
42
|
ops = document.querySelectorAll("#search-results li");
|
|
44
43
|
if (ops.length) {
|
|
@@ -49,27 +48,43 @@ class OperationsWaiter {
|
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Sets up the operation element with the correct attributes when selected
|
|
53
|
+
* @param {HTMLElement} element
|
|
54
|
+
*/
|
|
55
|
+
const _selectOperation = (element) => {
|
|
56
|
+
element.classList.add("selected-op");
|
|
57
|
+
element.scrollIntoView({block: "nearest"});
|
|
58
|
+
$(element).popover("show");
|
|
59
|
+
e.target.setAttribute("aria-activedescendant", element.id);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Sets up the operation element with the correct attributes when deselected
|
|
64
|
+
* @param {HTMLElement} element
|
|
65
|
+
*/
|
|
66
|
+
const _deselectOperation = (element) => {
|
|
67
|
+
element.classList.remove("selected-op");
|
|
68
|
+
$(element).popover("hide");
|
|
69
|
+
};
|
|
70
|
+
|
|
52
71
|
if (e.keyCode === 40) { // Down
|
|
53
72
|
e.preventDefault();
|
|
54
73
|
ops = document.querySelectorAll("#search-results li");
|
|
55
74
|
if (ops.length) {
|
|
56
75
|
selected = this.getSelectedOp(ops);
|
|
57
|
-
if (selected > -1)
|
|
58
|
-
ops[selected].classList.remove("selected-op");
|
|
59
|
-
}
|
|
76
|
+
if (selected > -1) _deselectOperation(ops[selected]);
|
|
60
77
|
if (selected === ops.length-1) selected = -1;
|
|
61
|
-
ops[selected+1]
|
|
78
|
+
_selectOperation(ops[selected+1]);
|
|
62
79
|
}
|
|
63
80
|
} else if (e.keyCode === 38) { // Up
|
|
64
81
|
e.preventDefault();
|
|
65
82
|
ops = document.querySelectorAll("#search-results li");
|
|
66
83
|
if (ops.length) {
|
|
67
84
|
selected = this.getSelectedOp(ops);
|
|
68
|
-
if (selected > -1)
|
|
69
|
-
ops[selected].classList.remove("selected-op");
|
|
70
|
-
}
|
|
85
|
+
if (selected > -1) _deselectOperation(ops[selected]);
|
|
71
86
|
if (selected === 0) selected = ops.length;
|
|
72
|
-
ops[selected-1]
|
|
87
|
+
_selectOperation(ops[selected-1]);
|
|
73
88
|
}
|
|
74
89
|
} else {
|
|
75
90
|
const searchResultsEl = document.getElementById("search-results");
|
|
@@ -83,11 +98,13 @@ class OperationsWaiter {
|
|
|
83
98
|
searchResultsEl.removeChild(searchResultsEl.firstChild);
|
|
84
99
|
}
|
|
85
100
|
|
|
101
|
+
document.querySelector("#search").removeAttribute("aria-activedescendant");
|
|
102
|
+
|
|
86
103
|
$("#categories .show").collapse("hide");
|
|
87
104
|
if (str) {
|
|
88
105
|
const matchedOps = this.filterOperations(str, true);
|
|
89
106
|
const matchedOpsHtml = matchedOps
|
|
90
|
-
.map(
|
|
107
|
+
.map((operation, idx) => operation.toStubHtml(false, `search-result-${idx}`))
|
|
91
108
|
.join("");
|
|
92
109
|
|
|
93
110
|
searchResultsEl.innerHTML = matchedOpsHtml;
|
|
@@ -103,7 +120,7 @@ class OperationsWaiter {
|
|
|
103
120
|
* @param {string} searchStr
|
|
104
121
|
* @param {boolean} highlight - Whether or not to highlight the matching string in the operation
|
|
105
122
|
* name and description
|
|
106
|
-
* @returns {
|
|
123
|
+
* @returns {HTMLOperation[]}
|
|
107
124
|
*/
|
|
108
125
|
filterOperations(inStr, highlight) {
|
|
109
126
|
const matchedOps = [];
|
|
@@ -589,8 +589,7 @@ Password: 282760`;
|
|
|
589
589
|
...[1, 3, 4, 5, 6, 7].map(version => it(`Analyze UUID v${version}`, () => {
|
|
590
590
|
const uuid = chef.generateUUID("", { "version": `v${version}` }).toString();
|
|
591
591
|
const result = chef.analyseUUID(uuid).toString();
|
|
592
|
-
|
|
593
|
-
assert.strictEqual(result, expected);
|
|
592
|
+
assert.ok(result.startsWith(`Version:\n${version}\n`), `Expected output to start with "Version:\\n${version}\\n", got: ${result}`);
|
|
594
593
|
})),
|
|
595
594
|
|
|
596
595
|
it("Generate UUID using defaults", () => {
|
|
@@ -598,7 +597,7 @@ Password: 282760`;
|
|
|
598
597
|
assert.ok(uuid);
|
|
599
598
|
|
|
600
599
|
const analysis = chef.analyseUUID(uuid).toString();
|
|
601
|
-
assert.
|
|
600
|
+
assert.ok(analysis.startsWith("Version:\n4\n"), `Expected output to start with "Version:\\n4\\n", got: ${analysis}`);
|
|
602
601
|
}),
|
|
603
602
|
|
|
604
603
|
it("Gzip, Gunzip", () => {
|
|
@@ -16,6 +16,7 @@ import { setLongTestFailure, logTestReport } from "../lib/utils.mjs";
|
|
|
16
16
|
import TestRegister from "../lib/TestRegister.mjs";
|
|
17
17
|
import "./tests/A1Z26CipherDecode.mjs";
|
|
18
18
|
import "./tests/AESKeyWrap.mjs";
|
|
19
|
+
import "./tests/AnalyseUUID.mjs";
|
|
19
20
|
import "./tests/AlternatingCaps.mjs";
|
|
20
21
|
import "./tests/AvroToJSON.mjs";
|
|
21
22
|
import "./tests/BaconCipher.mjs";
|
|
@@ -71,6 +72,7 @@ import "./tests/ExtractAudioMetadata.mjs";
|
|
|
71
72
|
import "./tests/ExtractEmailAddresses.mjs";
|
|
72
73
|
import "./tests/ExtractHashes.mjs";
|
|
73
74
|
import "./tests/ExtractIPAddresses.mjs";
|
|
75
|
+
import "./tests/Fernet.mjs";
|
|
74
76
|
import "./tests/Float.mjs";
|
|
75
77
|
import "./tests/FileTree.mjs";
|
|
76
78
|
import "./tests/FletcherChecksum.mjs";
|
|
@@ -134,6 +136,7 @@ import "./tests/ParseUDP.mjs";
|
|
|
134
136
|
import "./tests/PEMtoHex.mjs";
|
|
135
137
|
import "./tests/PGP.mjs";
|
|
136
138
|
import "./tests/PHP.mjs";
|
|
139
|
+
import "./tests/ParityBit.mjs";
|
|
137
140
|
import "./tests/PHPSerialize.mjs";
|
|
138
141
|
import "./tests/PowerSet.mjs";
|
|
139
142
|
import "./tests/Protobuf.mjs";
|
|
@@ -143,6 +146,8 @@ import "./tests/Rabbit.mjs";
|
|
|
143
146
|
import "./tests/RAKE.mjs";
|
|
144
147
|
import "./tests/Regex.mjs";
|
|
145
148
|
import "./tests/Register.mjs";
|
|
149
|
+
import "./tests/RegularExpression.mjs";
|
|
150
|
+
import "./tests/RenderMarkdown.mjs";
|
|
146
151
|
import "./tests/RisonEncodeDecode.mjs";
|
|
147
152
|
import "./tests/Rotate.mjs";
|
|
148
153
|
import "./tests/RSA.mjs";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analyse UUID tests
|
|
3
|
+
*
|
|
4
|
+
* @author ko80240 [csk.dev@proton.me]
|
|
5
|
+
* @copyright Crown Copyright 2023
|
|
6
|
+
* @license Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
9
|
+
|
|
10
|
+
TestRegister.addTests([
|
|
11
|
+
{
|
|
12
|
+
"name": "Analyse UUID: v1 UUID extracts timestamp, clock, and node",
|
|
13
|
+
"input": "cefa1760-28ee-11f1-9f95-1fb76af3e239",
|
|
14
|
+
"expectedOutput": "Version:\n1\n\nTimestamp:\n1774514156502\n\nTimestamp (ISO):\n2026-03-26T08:35:56.502Z\n\nNode:\n1F:B7:6A:F3:E2:39\n\nClock:\n8085\n\nUUID Integer:\n275119515460318071558429785403790975545",
|
|
15
|
+
"recipeConfig": [
|
|
16
|
+
{
|
|
17
|
+
"op": "Analyse UUID",
|
|
18
|
+
"args": [true]
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "Analyse UUID: v7 UUID extracts timestamp, randA, and randB",
|
|
24
|
+
"input": "019d294a-af64-7728-9524-26da08f50708",
|
|
25
|
+
"expectedOutput": "Version:\n7\n\nTimestamp:\n1774514253668\n\nTimestamp (ISO):\n2026-03-26T08:37:33.668Z\n\nRand A:\n1832\n\nRand B:\n952426DA08F50708\n\nUUID Integer:\n2145256098533991595556290452700595976",
|
|
26
|
+
"recipeConfig": [
|
|
27
|
+
{
|
|
28
|
+
"op": "Analyse UUID",
|
|
29
|
+
"args": [true]
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"name": "Analyse UUID: v4 UUID should show no metadata - not possible",
|
|
35
|
+
"input": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
|
|
36
|
+
"expectedOutput": "Version:\n4\n\nNo metadata available. Only versions 1, 6, 7 are supported.\n\nUUID Integer:\n324969006592305634633390616021200786553",
|
|
37
|
+
"recipeConfig": [
|
|
38
|
+
{
|
|
39
|
+
"op": "Analyse UUID",
|
|
40
|
+
"args": [true]
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "Analyse UUID: if the 'Include Metadata' option is false it should return not metadata",
|
|
46
|
+
"input": "cefa1760-28ee-11f1-9f95-1fb76af3e239",
|
|
47
|
+
"expectedOutput": "Version:\n1\n\nUUID Integer:\n275119515460318071558429785403790975545",
|
|
48
|
+
"recipeConfig": [
|
|
49
|
+
{
|
|
50
|
+
"op": "Analyse UUID",
|
|
51
|
+
"args": [false]
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "Analyse UUID: invalid UUID should return error message",
|
|
57
|
+
"input": "not-a-uuid",
|
|
58
|
+
"expectedOutput": "Invalid UUID",
|
|
59
|
+
"recipeConfig": [
|
|
60
|
+
{
|
|
61
|
+
"op": "Analyse UUID",
|
|
62
|
+
"args": [true]
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
]);
|
|
@@ -11,44 +11,70 @@ TestRegister.addTests([
|
|
|
11
11
|
{
|
|
12
12
|
name: "Extract email address",
|
|
13
13
|
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",
|
|
14
|
-
expectedOutput:
|
|
14
|
+
expectedOutput:
|
|
15
|
+
"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",
|
|
15
16
|
recipeConfig: [
|
|
16
17
|
{
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
op: "Extract email addresses",
|
|
19
|
+
args: [false],
|
|
19
20
|
},
|
|
20
21
|
],
|
|
21
22
|
},
|
|
22
23
|
{
|
|
23
24
|
name: "Extract email address - Display total",
|
|
24
25
|
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",
|
|
25
|
-
expectedOutput:
|
|
26
|
+
expectedOutput:
|
|
27
|
+
"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",
|
|
26
28
|
recipeConfig: [
|
|
27
29
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
op: "Extract email addresses",
|
|
31
|
+
args: [true],
|
|
30
32
|
},
|
|
31
33
|
],
|
|
32
34
|
},
|
|
33
35
|
{
|
|
34
36
|
name: "Extract email address (Internationalized)",
|
|
35
37
|
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",
|
|
36
|
-
expectedOutput:
|
|
38
|
+
expectedOutput:
|
|
39
|
+
"\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",
|
|
37
40
|
recipeConfig: [
|
|
38
41
|
{
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
op: "Extract email addresses",
|
|
43
|
+
args: [false],
|
|
41
44
|
},
|
|
42
45
|
],
|
|
43
46
|
},
|
|
44
47
|
{
|
|
45
48
|
name: "Extract email address - Display total (Internationalized)",
|
|
46
49
|
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",
|
|
47
|
-
expectedOutput:
|
|
50
|
+
expectedOutput:
|
|
51
|
+
"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",
|
|
48
52
|
recipeConfig: [
|
|
49
53
|
{
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
op: "Extract email addresses",
|
|
55
|
+
args: [true],
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "Extract email address - IP address",
|
|
61
|
+
input: "yaunwfkb\nexample@[127.0.0.1]\n091nvka",
|
|
62
|
+
expectedOutput: "example@[127.0.0.1]",
|
|
63
|
+
recipeConfig: [
|
|
64
|
+
{
|
|
65
|
+
op: "Extract email addresses",
|
|
66
|
+
args: [false],
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: "Extract email address - invalid IP address",
|
|
72
|
+
input: "yaunwfkb\nfalse_positive@[1.2.3.]\n091nvka",
|
|
73
|
+
expectedOutput: "",
|
|
74
|
+
recipeConfig: [
|
|
75
|
+
{
|
|
76
|
+
op: "Extract email addresses",
|
|
77
|
+
args: [false],
|
|
52
78
|
},
|
|
53
79
|
],
|
|
54
80
|
},
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @copyright Karsten Silkenbäumer 2019
|
|
6
6
|
* @license Apache-2.0
|
|
7
7
|
*/
|
|
8
|
-
import TestRegister from "
|
|
8
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
9
9
|
|
|
10
10
|
TestRegister.addTests([
|
|
11
11
|
{
|
|
@@ -47,7 +47,7 @@ TestRegister.addTests([
|
|
|
47
47
|
{
|
|
48
48
|
name: "Fernet Encrypt: no input",
|
|
49
49
|
input: "",
|
|
50
|
-
expectedMatch: /^
|
|
50
|
+
expectedMatch: /^gAAA[\w-]+={0,2}$/,
|
|
51
51
|
recipeConfig: [
|
|
52
52
|
{
|
|
53
53
|
op: "Fernet Encrypt",
|
|
@@ -69,12 +69,27 @@ TestRegister.addTests([
|
|
|
69
69
|
{
|
|
70
70
|
name: "Fernet Encrypt: valid arguments",
|
|
71
71
|
input: "This is a secret message.\n",
|
|
72
|
-
expectedMatch: /^
|
|
72
|
+
expectedMatch: /^gAAA[\w-]+={0,2}$/,
|
|
73
73
|
recipeConfig: [
|
|
74
74
|
{
|
|
75
75
|
op: "Fernet Encrypt",
|
|
76
76
|
args: ["MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI="]
|
|
77
77
|
}
|
|
78
78
|
],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "Fernet Encrypt/Decrypt: round trip",
|
|
82
|
+
input: "This is a secret message.\n",
|
|
83
|
+
expectedOutput: "This is a secret message.\n",
|
|
84
|
+
recipeConfig: [
|
|
85
|
+
{
|
|
86
|
+
op: "Fernet Encrypt",
|
|
87
|
+
args: ["MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI="]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
op: "Fernet Decrypt",
|
|
91
|
+
args: ["MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI="]
|
|
92
|
+
},
|
|
93
|
+
],
|
|
79
94
|
}
|
|
80
95
|
]);
|