cyberchef 9.39.5 → 9.41.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 +5 -0
- package/package.json +1 -1
- package/src/core/config/Categories.json +2 -0
- package/src/core/config/OperationConfig.json +47 -1
- package/src/core/config/modules/Ciphers.mjs +2 -0
- package/src/core/config/modules/Default.mjs +2 -0
- package/src/core/lib/Base85.mjs +5 -4
- package/src/core/operations/CaesarBoxCipher.mjs +61 -0
- package/src/core/operations/FromBase85.mjs +33 -3
- package/src/core/operations/PLISTViewer.mjs +133 -0
- package/src/core/operations/Subsection.mjs +1 -1
- package/src/core/operations/index.mjs +4 -0
- package/src/node/index.mjs +10 -0
- package/tests/lib/TestRegister.mjs +7 -0
- package/tests/operations/index.mjs +1 -0
- package/tests/operations/tests/CaesarBoxCipher.mjs +45 -0
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,9 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
13
13
|
|
|
14
14
|
## Details
|
|
15
15
|
|
|
16
|
+
### [9.40.0] - 2022-07-08
|
|
17
|
+
- Added 'P-list Viewer' operation [@n1073645] | [#906]
|
|
18
|
+
|
|
16
19
|
### [9.39.0] - 2022-06-09
|
|
17
20
|
- Added 'ELF Info' operation [@n1073645] | [#1364]
|
|
18
21
|
|
|
@@ -294,6 +297,7 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
294
297
|
|
|
295
298
|
|
|
296
299
|
|
|
300
|
+
[9.40.0]: https://github.com/gchq/CyberChef/releases/tag/v9.40.0
|
|
297
301
|
[9.39.0]: https://github.com/gchq/CyberChef/releases/tag/v9.39.0
|
|
298
302
|
[9.38.0]: https://github.com/gchq/CyberChef/releases/tag/v9.38.0
|
|
299
303
|
[9.37.0]: https://github.com/gchq/CyberChef/releases/tag/v9.37.0
|
|
@@ -491,6 +495,7 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
491
495
|
[#674]: https://github.com/gchq/CyberChef/pull/674
|
|
492
496
|
[#683]: https://github.com/gchq/CyberChef/pull/683
|
|
493
497
|
[#865]: https://github.com/gchq/CyberChef/pull/865
|
|
498
|
+
[#906]: https://github.com/gchq/CyberChef/pull/906
|
|
494
499
|
[#912]: https://github.com/gchq/CyberChef/pull/912
|
|
495
500
|
[#917]: https://github.com/gchq/CyberChef/pull/917
|
|
496
501
|
[#934]: https://github.com/gchq/CyberChef/pull/934
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyberchef",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.41.0",
|
|
4
4
|
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
|
5
5
|
"author": "n1474335 <n1474335@gmail.com>",
|
|
6
6
|
"homepage": "https://gchq.github.io/CyberChef",
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
"Bacon Cipher Decode",
|
|
98
98
|
"Bifid Cipher Encode",
|
|
99
99
|
"Bifid Cipher Decode",
|
|
100
|
+
"Caesar Box Cipher",
|
|
100
101
|
"Affine Cipher Encode",
|
|
101
102
|
"Affine Cipher Decode",
|
|
102
103
|
"A1Z26 Cipher Encode",
|
|
@@ -457,6 +458,7 @@
|
|
|
457
458
|
"Frequency distribution",
|
|
458
459
|
"Index of Coincidence",
|
|
459
460
|
"Chi Square",
|
|
461
|
+
"P-list Viewer",
|
|
460
462
|
"Disassemble x86",
|
|
461
463
|
"Pseudo-Random Number Generator",
|
|
462
464
|
"Generate UUID",
|
|
@@ -1469,6 +1469,22 @@
|
|
|
1469
1469
|
"manualBake": false,
|
|
1470
1470
|
"args": []
|
|
1471
1471
|
},
|
|
1472
|
+
"Caesar Box Cipher": {
|
|
1473
|
+
"module": "Ciphers",
|
|
1474
|
+
"description": "Caesar Box is a transposition cipher used in the Roman Empire, in which letters of the message are written in rows in a square (or a rectangle) and then, read by column.",
|
|
1475
|
+
"infoURL": "https://www.dcode.fr/caesar-box-cipher",
|
|
1476
|
+
"inputType": "string",
|
|
1477
|
+
"outputType": "string",
|
|
1478
|
+
"flowControl": false,
|
|
1479
|
+
"manualBake": false,
|
|
1480
|
+
"args": [
|
|
1481
|
+
{
|
|
1482
|
+
"name": "Box Height",
|
|
1483
|
+
"type": "number",
|
|
1484
|
+
"value": 1
|
|
1485
|
+
}
|
|
1486
|
+
]
|
|
1487
|
+
},
|
|
1472
1488
|
"Cartesian Product": {
|
|
1473
1489
|
"module": "Default",
|
|
1474
1490
|
"description": "Calculates the cartesian product of multiple sets of data, returning all possible combinations.",
|
|
@@ -6006,6 +6022,26 @@
|
|
|
6006
6022
|
"type": "boolean",
|
|
6007
6023
|
"value": true
|
|
6008
6024
|
}
|
|
6025
|
+
],
|
|
6026
|
+
"checks": [
|
|
6027
|
+
{
|
|
6028
|
+
"pattern": "^\\s*(?:<~)?[\\s!-uz]*[!-uz]{15}[\\s!-uz]*(?:~>)?\\s*$",
|
|
6029
|
+
"args": [
|
|
6030
|
+
"!-u"
|
|
6031
|
+
]
|
|
6032
|
+
},
|
|
6033
|
+
{
|
|
6034
|
+
"pattern": "^[\\s0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]*[0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]{15}[\\s0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]*$",
|
|
6035
|
+
"args": [
|
|
6036
|
+
"0-9a-zA-Z.\\-:+=^!/*?&<>()[]{}@%$#"
|
|
6037
|
+
]
|
|
6038
|
+
},
|
|
6039
|
+
{
|
|
6040
|
+
"pattern": "^[\\s0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]*[0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]{15}[\\s0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]*$",
|
|
6041
|
+
"args": [
|
|
6042
|
+
"0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~"
|
|
6043
|
+
]
|
|
6044
|
+
}
|
|
6009
6045
|
]
|
|
6010
6046
|
},
|
|
6011
6047
|
"From Binary": {
|
|
@@ -8750,6 +8786,16 @@
|
|
|
8750
8786
|
}
|
|
8751
8787
|
]
|
|
8752
8788
|
},
|
|
8789
|
+
"P-list Viewer": {
|
|
8790
|
+
"module": "Default",
|
|
8791
|
+
"description": "In the macOS, iOS, NeXTSTEP, and GNUstep programming frameworks, property list files are files that store serialized objects. Property list files use the filename extension .plist, and thus are often referred to as p-list files.<br><br>This operation displays plist files in a human readable format.",
|
|
8792
|
+
"infoURL": "https://wikipedia.org/wiki/Property_list",
|
|
8793
|
+
"inputType": "string",
|
|
8794
|
+
"outputType": "string",
|
|
8795
|
+
"flowControl": false,
|
|
8796
|
+
"manualBake": false,
|
|
8797
|
+
"args": []
|
|
8798
|
+
},
|
|
8753
8799
|
"Pad lines": {
|
|
8754
8800
|
"module": "Default",
|
|
8755
8801
|
"description": "Add the specified number of the specified character to the beginning or end of each line",
|
|
@@ -12927,7 +12973,7 @@
|
|
|
12927
12973
|
},
|
|
12928
12974
|
"Subsection": {
|
|
12929
12975
|
"module": "Default",
|
|
12930
|
-
"description": "Select a part of the input data using a regular expression (regex), and run all subsequent operations on each match separately.<br><br>You can use up to one capture group, where the recipe will only be run on the data in the capture group. If there's more than one capture group, only the first one will be operated on.",
|
|
12976
|
+
"description": "Select a part of the input data using a regular expression (regex), and run all subsequent operations on each match separately.<br><br>You can use up to one capture group, where the recipe will only be run on the data in the capture group. If there's more than one capture group, only the first one will be operated on.<br><br>Use the Merge operation to reset the effects of subsection.",
|
|
12931
12977
|
"infoURL": "",
|
|
12932
12978
|
"inputType": "string",
|
|
12933
12979
|
"outputType": "string",
|
|
@@ -16,6 +16,7 @@ import BifidCipherDecode from "../../operations/BifidCipherDecode.mjs";
|
|
|
16
16
|
import BifidCipherEncode from "../../operations/BifidCipherEncode.mjs";
|
|
17
17
|
import BlowfishDecrypt from "../../operations/BlowfishDecrypt.mjs";
|
|
18
18
|
import BlowfishEncrypt from "../../operations/BlowfishEncrypt.mjs";
|
|
19
|
+
import CaesarBoxCipher from "../../operations/CaesarBoxCipher.mjs";
|
|
19
20
|
import DESDecrypt from "../../operations/DESDecrypt.mjs";
|
|
20
21
|
import DESEncrypt from "../../operations/DESEncrypt.mjs";
|
|
21
22
|
import DeriveEVPKey from "../../operations/DeriveEVPKey.mjs";
|
|
@@ -53,6 +54,7 @@ OpModules.Ciphers = {
|
|
|
53
54
|
"Bifid Cipher Encode": BifidCipherEncode,
|
|
54
55
|
"Blowfish Decrypt": BlowfishDecrypt,
|
|
55
56
|
"Blowfish Encrypt": BlowfishEncrypt,
|
|
57
|
+
"Caesar Box Cipher": CaesarBoxCipher,
|
|
56
58
|
"DES Decrypt": DESDecrypt,
|
|
57
59
|
"DES Encrypt": DESEncrypt,
|
|
58
60
|
"Derive EVP key": DeriveEVPKey,
|
|
@@ -92,6 +92,7 @@ import OR from "../../operations/OR.mjs";
|
|
|
92
92
|
import OffsetChecker from "../../operations/OffsetChecker.mjs";
|
|
93
93
|
import PEMToHex from "../../operations/PEMToHex.mjs";
|
|
94
94
|
import PHPDeserialize from "../../operations/PHPDeserialize.mjs";
|
|
95
|
+
import PLISTViewer from "../../operations/PLISTViewer.mjs";
|
|
95
96
|
import PadLines from "../../operations/PadLines.mjs";
|
|
96
97
|
import ParseColourCode from "../../operations/ParseColourCode.mjs";
|
|
97
98
|
import ParseDateTime from "../../operations/ParseDateTime.mjs";
|
|
@@ -261,6 +262,7 @@ OpModules.Default = {
|
|
|
261
262
|
"Offset checker": OffsetChecker,
|
|
262
263
|
"PEM to Hex": PEMToHex,
|
|
263
264
|
"PHP Deserialize": PHPDeserialize,
|
|
265
|
+
"P-list Viewer": PLISTViewer,
|
|
264
266
|
"Pad lines": PadLines,
|
|
265
267
|
"Parse colour code": ParseColourCode,
|
|
266
268
|
"Parse DateTime": ParseDateTime,
|
package/src/core/lib/Base85.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import Utils from "../Utils.mjs";
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Base85 resources.
|
|
3
5
|
*
|
|
@@ -32,13 +34,12 @@ export const ALPHABET_OPTIONS = [
|
|
|
32
34
|
* @returns {string}
|
|
33
35
|
*/
|
|
34
36
|
export function alphabetName(alphabet) {
|
|
35
|
-
alphabet = alphabet
|
|
36
|
-
alphabet = alphabet.replace(/"/g, """);
|
|
37
|
-
alphabet = alphabet.replace(/\\/g, "\");
|
|
37
|
+
alphabet = escape(alphabet);
|
|
38
38
|
let name;
|
|
39
39
|
|
|
40
40
|
ALPHABET_OPTIONS.forEach(function(a) {
|
|
41
|
-
|
|
41
|
+
const expanded = Utils.expandAlphRange(a.value).join("");
|
|
42
|
+
if (alphabet === escape(expanded)) name = a.name;
|
|
42
43
|
});
|
|
43
44
|
|
|
44
45
|
return name;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author n1073645 [n1073645@gmail.com]
|
|
3
|
+
* @copyright Crown Copyright 2020
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Caesar Box Cipher operation
|
|
11
|
+
*/
|
|
12
|
+
class CaesarBoxCipher extends Operation {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* CaesarBoxCipher constructor
|
|
16
|
+
*/
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
|
|
20
|
+
this.name = "Caesar Box Cipher";
|
|
21
|
+
this.module = "Ciphers";
|
|
22
|
+
this.description = "Caesar Box is a transposition cipher used in the Roman Empire, in which letters of the message are written in rows in a square (or a rectangle) and then, read by column.";
|
|
23
|
+
this.infoURL = "https://www.dcode.fr/caesar-box-cipher";
|
|
24
|
+
this.inputType = "string";
|
|
25
|
+
this.outputType = "string";
|
|
26
|
+
this.args = [
|
|
27
|
+
{
|
|
28
|
+
name: "Box Height",
|
|
29
|
+
type: "number",
|
|
30
|
+
value: 1
|
|
31
|
+
}
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {string} input
|
|
37
|
+
* @param {Object[]} args
|
|
38
|
+
* @returns {string}
|
|
39
|
+
*/
|
|
40
|
+
run(input, args) {
|
|
41
|
+
const tableHeight = args[0];
|
|
42
|
+
const tableWidth = Math.ceil(input.length / tableHeight);
|
|
43
|
+
while (input.indexOf(" ") !== -1)
|
|
44
|
+
input = input.replace(" ", "");
|
|
45
|
+
for (let i = 0; i < (tableHeight * tableWidth) - input.length; i++) {
|
|
46
|
+
input += "\x00";
|
|
47
|
+
}
|
|
48
|
+
let result = "";
|
|
49
|
+
for (let i = 0; i < tableHeight; i++) {
|
|
50
|
+
for (let j = i; j < input.length; j += tableHeight) {
|
|
51
|
+
if (input.charAt(j) !== "\x00") {
|
|
52
|
+
result += input.charAt(j);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default CaesarBoxCipher;
|
|
@@ -38,6 +38,35 @@ class FromBase85 extends Operation {
|
|
|
38
38
|
value: true
|
|
39
39
|
},
|
|
40
40
|
];
|
|
41
|
+
this.checks = [
|
|
42
|
+
{
|
|
43
|
+
pattern:
|
|
44
|
+
"^\\s*(?:<~)?" + // Optional whitespace and starting marker
|
|
45
|
+
"[\\s!-uz]*" + // Any amount of base85 characters and whitespace
|
|
46
|
+
"[!-uz]{15}" + // At least 15 continoues base85 characters without whitespace
|
|
47
|
+
"[\\s!-uz]*" + // Any amount of base85 characters and whitespace
|
|
48
|
+
"(?:~>)?\\s*$", // Optional ending marker and whitespace
|
|
49
|
+
args: ["!-u"],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
pattern:
|
|
53
|
+
"^" +
|
|
54
|
+
"[\\s0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]*" +
|
|
55
|
+
"[0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]{15}" + // At least 15 continoues base85 characters without whitespace
|
|
56
|
+
"[\\s0-9a-zA-Z.\\-:+=^!/*?&<>()[\\]{}@%$#]*" +
|
|
57
|
+
"$",
|
|
58
|
+
args: ["0-9a-zA-Z.\\-:+=^!/*?&<>()[]{}@%$#"],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
pattern:
|
|
62
|
+
"^" +
|
|
63
|
+
"[\\s0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]*" +
|
|
64
|
+
"[0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]{15}" + // At least 15 continoues base85 characters without whitespace
|
|
65
|
+
"[\\s0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~]*" +
|
|
66
|
+
"$",
|
|
67
|
+
args: ["0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~"],
|
|
68
|
+
},
|
|
69
|
+
];
|
|
41
70
|
}
|
|
42
71
|
|
|
43
72
|
/**
|
|
@@ -56,6 +85,10 @@ class FromBase85 extends Operation {
|
|
|
56
85
|
throw new OperationError("Alphabet must be of length 85");
|
|
57
86
|
}
|
|
58
87
|
|
|
88
|
+
// Remove delimiters if present
|
|
89
|
+
const matches = input.match(/^<~(.+?)~>$/);
|
|
90
|
+
if (matches !== null) input = matches[1];
|
|
91
|
+
|
|
59
92
|
// Remove non-alphabet characters
|
|
60
93
|
if (removeNonAlphChars) {
|
|
61
94
|
const re = new RegExp("[^" + alphabet.replace(/[[\]\\\-^$]/g, "\\$&") + "]", "g");
|
|
@@ -64,9 +97,6 @@ class FromBase85 extends Operation {
|
|
|
64
97
|
|
|
65
98
|
if (input.length === 0) return [];
|
|
66
99
|
|
|
67
|
-
const matches = input.match(/<~(.+?)~>/);
|
|
68
|
-
if (matches !== null) input = matches[1];
|
|
69
|
-
|
|
70
100
|
let i = 0;
|
|
71
101
|
let block, blockBytes;
|
|
72
102
|
while (i < input.length) {
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author n1073645 [n1073645@gmail.com]
|
|
3
|
+
* @copyright Crown Copyright 2019
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* P-list Viewer operation
|
|
11
|
+
*/
|
|
12
|
+
class PlistViewer extends Operation {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* PlistViewer constructor
|
|
16
|
+
*/
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
|
|
20
|
+
this.name = "P-list Viewer";
|
|
21
|
+
this.module = "Default";
|
|
22
|
+
this.description = "In the macOS, iOS, NeXTSTEP, and GNUstep programming frameworks, property list files are files that store serialized objects. Property list files use the filename extension .plist, and thus are often referred to as p-list files.<br><br>This operation displays plist files in a human readable format.";
|
|
23
|
+
this.infoURL = "https://wikipedia.org/wiki/Property_list";
|
|
24
|
+
this.inputType = "string";
|
|
25
|
+
this.outputType = "string";
|
|
26
|
+
this.args = [];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {string} input
|
|
31
|
+
* @param {Object[]} args
|
|
32
|
+
* @returns {string}
|
|
33
|
+
*/
|
|
34
|
+
run(input, args) {
|
|
35
|
+
|
|
36
|
+
// Regexes are designed to transform the xml format into a more readable string format.
|
|
37
|
+
input = input.slice(input.indexOf("<plist"))
|
|
38
|
+
.replace(/<plist.+>/g, "plist => ")
|
|
39
|
+
.replace(/<dict>/g, "{")
|
|
40
|
+
.replace(/<\/dict>/g, "}")
|
|
41
|
+
.replace(/<array>/g, "[")
|
|
42
|
+
.replace(/<\/array>/g, "]")
|
|
43
|
+
.replace(/<key>.+<\/key>/g, m => `${m.slice(5, m.indexOf(/<\/key>/g)-5)}\t=> `)
|
|
44
|
+
.replace(/<real>.+<\/real>/g, m => `${m.slice(6, m.indexOf(/<\/real>/g)-6)}\n`)
|
|
45
|
+
.replace(/<string>.+<\/string>/g, m => `"${m.slice(8, m.indexOf(/<\/string>/g)-8)}"\n`)
|
|
46
|
+
.replace(/<integer>.+<\/integer>/g, m => `${m.slice(9, m.indexOf(/<\/integer>/g)-9)}\n`)
|
|
47
|
+
.replace(/<false\/>/g, m => "false")
|
|
48
|
+
.replace(/<true\/>/g, m => "true")
|
|
49
|
+
.replace(/<\/plist>/g, "/plist")
|
|
50
|
+
.replace(/<date>.+<\/date>/g, m => `${m.slice(6, m.indexOf(/<\/integer>/g)-6)}`)
|
|
51
|
+
.replace(/<data>(\s|.)+?<\/data>/g, m => `${m.slice(6, m.indexOf(/<\/data>/g)-6)}`)
|
|
52
|
+
.replace(/[ \t\r\f\v]/g, "");
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Depending on the type of brace, it will increment the depth and amount of arrays accordingly.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} elem
|
|
58
|
+
* @param {array} vals
|
|
59
|
+
* @param {number} offset
|
|
60
|
+
*/
|
|
61
|
+
function braces(elem, vals, offset) {
|
|
62
|
+
const temp = vals.indexOf(elem);
|
|
63
|
+
if (temp !== -1) {
|
|
64
|
+
depthCount += offset;
|
|
65
|
+
if (temp === 1)
|
|
66
|
+
arrCount += offset;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let result = "";
|
|
71
|
+
let arrCount = 0;
|
|
72
|
+
let depthCount = 0;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Formats the input after the regex has replaced all of the relevant parts.
|
|
76
|
+
*
|
|
77
|
+
* @param {array} input
|
|
78
|
+
* @param {number} index
|
|
79
|
+
*/
|
|
80
|
+
function printIt(input, index) {
|
|
81
|
+
if (!(input.length))
|
|
82
|
+
return;
|
|
83
|
+
|
|
84
|
+
let temp = "";
|
|
85
|
+
const origArr = arrCount;
|
|
86
|
+
let currElem = input[0];
|
|
87
|
+
|
|
88
|
+
// If the current position points at a larger dynamic structure.
|
|
89
|
+
if (currElem.indexOf("=>") !== -1) {
|
|
90
|
+
|
|
91
|
+
// If the LHS also points at a larger structure (nested plists in a dictionary).
|
|
92
|
+
if (input[1].indexOf("=>") !== -1)
|
|
93
|
+
temp = currElem.slice(0, -2) + " => " + input[1].slice(0, -2) + " =>\n";
|
|
94
|
+
else
|
|
95
|
+
temp = currElem.slice(0, -2) + " => " + input[1] + "\n";
|
|
96
|
+
|
|
97
|
+
input = input.slice(1);
|
|
98
|
+
} else {
|
|
99
|
+
// Controls the tab depth for how many closing braces there have been.
|
|
100
|
+
|
|
101
|
+
braces(currElem, ["}", "]"], -1);
|
|
102
|
+
|
|
103
|
+
// Has to be here since the formatting breaks otherwise.
|
|
104
|
+
temp = currElem + "\n";
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
currElem = input[0];
|
|
108
|
+
|
|
109
|
+
// Tab out to the correct distance.
|
|
110
|
+
result += ("\t".repeat(depthCount));
|
|
111
|
+
|
|
112
|
+
// If it is enclosed in an array show index.
|
|
113
|
+
if (arrCount > 0 && currElem !== "]")
|
|
114
|
+
result += index.toString() + " => ";
|
|
115
|
+
|
|
116
|
+
result += temp;
|
|
117
|
+
|
|
118
|
+
// Controls the tab depth for how many opening braces there have been.
|
|
119
|
+
braces(currElem, ["{", "["], 1);
|
|
120
|
+
|
|
121
|
+
// If there has been a new array then reset index.
|
|
122
|
+
if (arrCount > origArr)
|
|
123
|
+
return printIt(input.slice(1), 0);
|
|
124
|
+
return printIt(input.slice(1), ++index);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
input = input.split("\n").filter(e => e !== "");
|
|
128
|
+
printIt(input, 0);
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export default PlistViewer;
|
|
@@ -22,7 +22,7 @@ class Subsection extends Operation {
|
|
|
22
22
|
this.name = "Subsection";
|
|
23
23
|
this.flowControl = true;
|
|
24
24
|
this.module = "Default";
|
|
25
|
-
this.description = "Select a part of the input data using a regular expression (regex), and run all subsequent operations on each match separately.<br><br>You can use up to one capture group, where the recipe will only be run on the data in the capture group. If there's more than one capture group, only the first one will be operated on.";
|
|
25
|
+
this.description = "Select a part of the input data using a regular expression (regex), and run all subsequent operations on each match separately.<br><br>You can use up to one capture group, where the recipe will only be run on the data in the capture group. If there's more than one capture group, only the first one will be operated on.<br><br>Use the Merge operation to reset the effects of subsection.";
|
|
26
26
|
this.infoURL = "";
|
|
27
27
|
this.inputType = "string";
|
|
28
28
|
this.outputType = "string";
|
|
@@ -48,6 +48,7 @@ import CSSMinify from "./CSSMinify.mjs";
|
|
|
48
48
|
import CSSSelector from "./CSSSelector.mjs";
|
|
49
49
|
import CSVToJSON from "./CSVToJSON.mjs";
|
|
50
50
|
import CTPH from "./CTPH.mjs";
|
|
51
|
+
import CaesarBoxCipher from "./CaesarBoxCipher.mjs";
|
|
51
52
|
import CartesianProduct from "./CartesianProduct.mjs";
|
|
52
53
|
import ChangeIPFormat from "./ChangeIPFormat.mjs";
|
|
53
54
|
import ChiSquare from "./ChiSquare.mjs";
|
|
@@ -220,6 +221,7 @@ import PGPEncrypt from "./PGPEncrypt.mjs";
|
|
|
220
221
|
import PGPEncryptAndSign from "./PGPEncryptAndSign.mjs";
|
|
221
222
|
import PGPVerify from "./PGPVerify.mjs";
|
|
222
223
|
import PHPDeserialize from "./PHPDeserialize.mjs";
|
|
224
|
+
import PLISTViewer from "./PLISTViewer.mjs";
|
|
223
225
|
import PadLines from "./PadLines.mjs";
|
|
224
226
|
import ParseASN1HexString from "./ParseASN1HexString.mjs";
|
|
225
227
|
import ParseColourCode from "./ParseColourCode.mjs";
|
|
@@ -422,6 +424,7 @@ export {
|
|
|
422
424
|
CSSSelector,
|
|
423
425
|
CSVToJSON,
|
|
424
426
|
CTPH,
|
|
427
|
+
CaesarBoxCipher,
|
|
425
428
|
CartesianProduct,
|
|
426
429
|
ChangeIPFormat,
|
|
427
430
|
ChiSquare,
|
|
@@ -594,6 +597,7 @@ export {
|
|
|
594
597
|
PGPEncryptAndSign,
|
|
595
598
|
PGPVerify,
|
|
596
599
|
PHPDeserialize,
|
|
600
|
+
PLISTViewer,
|
|
597
601
|
PadLines,
|
|
598
602
|
ParseASN1HexString,
|
|
599
603
|
ParseColourCode,
|
package/src/node/index.mjs
CHANGED
|
@@ -58,6 +58,7 @@ import {
|
|
|
58
58
|
CSSSelector as core_CSSSelector,
|
|
59
59
|
CSVToJSON as core_CSVToJSON,
|
|
60
60
|
CTPH as core_CTPH,
|
|
61
|
+
CaesarBoxCipher as core_CaesarBoxCipher,
|
|
61
62
|
CartesianProduct as core_CartesianProduct,
|
|
62
63
|
ChangeIPFormat as core_ChangeIPFormat,
|
|
63
64
|
ChiSquare as core_ChiSquare,
|
|
@@ -221,6 +222,7 @@ import {
|
|
|
221
222
|
PGPEncryptAndSign as core_PGPEncryptAndSign,
|
|
222
223
|
PGPVerify as core_PGPVerify,
|
|
223
224
|
PHPDeserialize as core_PHPDeserialize,
|
|
225
|
+
PLISTViewer as core_PLISTViewer,
|
|
224
226
|
PadLines as core_PadLines,
|
|
225
227
|
ParseASN1HexString as core_ParseASN1HexString,
|
|
226
228
|
ParseColourCode as core_ParseColourCode,
|
|
@@ -432,6 +434,7 @@ function generateChef() {
|
|
|
432
434
|
"CSSSelector": _wrap(core_CSSSelector),
|
|
433
435
|
"CSVToJSON": _wrap(core_CSVToJSON),
|
|
434
436
|
"CTPH": _wrap(core_CTPH),
|
|
437
|
+
"caesarBoxCipher": _wrap(core_CaesarBoxCipher),
|
|
435
438
|
"cartesianProduct": _wrap(core_CartesianProduct),
|
|
436
439
|
"changeIPFormat": _wrap(core_ChangeIPFormat),
|
|
437
440
|
"chiSquare": _wrap(core_ChiSquare),
|
|
@@ -595,6 +598,7 @@ function generateChef() {
|
|
|
595
598
|
"PGPEncryptAndSign": _wrap(core_PGPEncryptAndSign),
|
|
596
599
|
"PGPVerify": _wrap(core_PGPVerify),
|
|
597
600
|
"PHPDeserialize": _wrap(core_PHPDeserialize),
|
|
601
|
+
"PLISTViewer": _wrap(core_PLISTViewer),
|
|
598
602
|
"padLines": _wrap(core_PadLines),
|
|
599
603
|
"parseASN1HexString": _wrap(core_ParseASN1HexString),
|
|
600
604
|
"parseColourCode": _wrap(core_ParseColourCode),
|
|
@@ -814,6 +818,7 @@ const CSSMinify = chef.CSSMinify;
|
|
|
814
818
|
const CSSSelector = chef.CSSSelector;
|
|
815
819
|
const CSVToJSON = chef.CSVToJSON;
|
|
816
820
|
const CTPH = chef.CTPH;
|
|
821
|
+
const caesarBoxCipher = chef.caesarBoxCipher;
|
|
817
822
|
const cartesianProduct = chef.cartesianProduct;
|
|
818
823
|
const changeIPFormat = chef.changeIPFormat;
|
|
819
824
|
const chiSquare = chef.chiSquare;
|
|
@@ -986,6 +991,7 @@ const PGPEncrypt = chef.PGPEncrypt;
|
|
|
986
991
|
const PGPEncryptAndSign = chef.PGPEncryptAndSign;
|
|
987
992
|
const PGPVerify = chef.PGPVerify;
|
|
988
993
|
const PHPDeserialize = chef.PHPDeserialize;
|
|
994
|
+
const PLISTViewer = chef.PLISTViewer;
|
|
989
995
|
const padLines = chef.padLines;
|
|
990
996
|
const parseASN1HexString = chef.parseASN1HexString;
|
|
991
997
|
const parseColourCode = chef.parseColourCode;
|
|
@@ -1190,6 +1196,7 @@ const operations = [
|
|
|
1190
1196
|
CSSSelector,
|
|
1191
1197
|
CSVToJSON,
|
|
1192
1198
|
CTPH,
|
|
1199
|
+
caesarBoxCipher,
|
|
1193
1200
|
cartesianProduct,
|
|
1194
1201
|
changeIPFormat,
|
|
1195
1202
|
chiSquare,
|
|
@@ -1362,6 +1369,7 @@ const operations = [
|
|
|
1362
1369
|
PGPEncryptAndSign,
|
|
1363
1370
|
PGPVerify,
|
|
1364
1371
|
PHPDeserialize,
|
|
1372
|
+
PLISTViewer,
|
|
1365
1373
|
padLines,
|
|
1366
1374
|
parseASN1HexString,
|
|
1367
1375
|
parseColourCode,
|
|
@@ -1570,6 +1578,7 @@ export {
|
|
|
1570
1578
|
CSSSelector,
|
|
1571
1579
|
CSVToJSON,
|
|
1572
1580
|
CTPH,
|
|
1581
|
+
caesarBoxCipher,
|
|
1573
1582
|
cartesianProduct,
|
|
1574
1583
|
changeIPFormat,
|
|
1575
1584
|
chiSquare,
|
|
@@ -1742,6 +1751,7 @@ export {
|
|
|
1742
1751
|
PGPEncryptAndSign,
|
|
1743
1752
|
PGPVerify,
|
|
1744
1753
|
PHPDeserialize,
|
|
1754
|
+
PLISTViewer,
|
|
1745
1755
|
padLines,
|
|
1746
1756
|
parseASN1HexString,
|
|
1747
1757
|
parseColourCode,
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import Chef from "../../src/core/Chef.mjs";
|
|
13
13
|
import Utils from "../../src/core/Utils.mjs";
|
|
14
14
|
import cliProgress from "cli-progress";
|
|
15
|
+
import log from "loglevel";
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Object to store and run the list of tests.
|
|
@@ -50,6 +51,9 @@ class TestRegister {
|
|
|
50
51
|
* Runs all the tests in the register.
|
|
51
52
|
*/
|
|
52
53
|
async runTests () {
|
|
54
|
+
// Turn off logging to avoid messy errors
|
|
55
|
+
log.setLevel("silent", false);
|
|
56
|
+
|
|
53
57
|
const progBar = new cliProgress.SingleBar({
|
|
54
58
|
format: formatter,
|
|
55
59
|
stopOnComplete: true
|
|
@@ -128,6 +132,9 @@ class TestRegister {
|
|
|
128
132
|
progBar.increment();
|
|
129
133
|
}
|
|
130
134
|
|
|
135
|
+
// Turn logging back on
|
|
136
|
+
log.setLevel("info", false);
|
|
137
|
+
|
|
131
138
|
return testResults;
|
|
132
139
|
}
|
|
133
140
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Caesar Box Cipher tests.
|
|
3
|
+
*
|
|
4
|
+
* @author n1073645 [n1073645@gmail.com]
|
|
5
|
+
*
|
|
6
|
+
* @copyright Crown Copyright 2020
|
|
7
|
+
* @license Apache-2.0
|
|
8
|
+
*/
|
|
9
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
10
|
+
|
|
11
|
+
TestRegister.addTests([
|
|
12
|
+
{
|
|
13
|
+
name: "Caesar Box Cipher: nothing",
|
|
14
|
+
input: "",
|
|
15
|
+
expectedOutput: "",
|
|
16
|
+
recipeConfig: [
|
|
17
|
+
{
|
|
18
|
+
op: "Caesar Box Cipher",
|
|
19
|
+
args: ["1"],
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: "Caesar Box Cipher: Hello World!",
|
|
25
|
+
input: "Hello World!",
|
|
26
|
+
expectedOutput: "Hlodeor!lWl",
|
|
27
|
+
recipeConfig: [
|
|
28
|
+
{
|
|
29
|
+
op: "Caesar Box Cipher",
|
|
30
|
+
args: ["3"],
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: "Caesar Box Cipher: Hello World!",
|
|
36
|
+
input: "Hlodeor!lWl",
|
|
37
|
+
expectedOutput: "HelloWorld!",
|
|
38
|
+
recipeConfig: [
|
|
39
|
+
{
|
|
40
|
+
op: "Caesar Box Cipher",
|
|
41
|
+
args: ["4"],
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
}
|
|
45
|
+
]);
|