cyberchef 9.45.0 → 9.46.2
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 +12 -0
- package/README.md +6 -6
- package/package.json +2 -2
- package/src/core/config/Categories.json +2 -0
- package/src/core/config/OperationConfig.json +32 -0
- package/src/core/config/modules/Ciphers.mjs +4 -0
- package/src/core/operations/CetaceanCipherDecode.mjs +63 -0
- package/src/core/operations/CetaceanCipherEncode.mjs +51 -0
- package/src/core/operations/JPathExpression.mjs +21 -12
- package/src/core/operations/JSONToCSV.mjs +5 -2
- package/src/core/operations/index.mjs +4 -0
- package/src/node/index.mjs +10 -0
- package/src/web/stylesheets/utils/_overrides.css +20 -5
- package/tests/operations/index.mjs +2 -0
- package/tests/operations/tests/CetaceanCipherDecode.mjs +22 -0
- package/tests/operations/tests/CetaceanCipherEncode.mjs +22 -0
- package/tests/operations/tests/Code.mjs +25 -10
- package/tests/operations/tests/JSONtoCSV.mjs +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,12 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
13
13
|
|
|
14
14
|
## Details
|
|
15
15
|
|
|
16
|
+
### [9.46.0] - 2022-07-08
|
|
17
|
+
- Added 'Cetacean Cipher Encode' and 'Cetacean Cipher Decode' operations [@valdelaseras] | [#1308]
|
|
18
|
+
|
|
19
|
+
### [9.45.0] - 2022-07-08
|
|
20
|
+
- Added 'ROT8000' operation [@thomasleplus] | [#1250]
|
|
21
|
+
|
|
16
22
|
### [9.44.0] - 2022-07-08
|
|
17
23
|
- Added 'LZString Compress' and 'LZString Decompress' operations [@crespyl] | [#1266]
|
|
18
24
|
|
|
@@ -309,6 +315,8 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
309
315
|
|
|
310
316
|
|
|
311
317
|
|
|
318
|
+
[9.46.0]: https://github.com/gchq/CyberChef/releases/tag/v9.46.0
|
|
319
|
+
[9.45.0]: https://github.com/gchq/CyberChef/releases/tag/v9.45.0
|
|
312
320
|
[9.44.0]: https://github.com/gchq/CyberChef/releases/tag/v9.44.0
|
|
313
321
|
[9.43.0]: https://github.com/gchq/CyberChef/releases/tag/v9.43.0
|
|
314
322
|
[9.42.0]: https://github.com/gchq/CyberChef/releases/tag/v9.42.0
|
|
@@ -440,6 +448,8 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
440
448
|
[@swesven]: https://github.com/swesven
|
|
441
449
|
[@mikecat]: https://github.com/mikecat
|
|
442
450
|
[@crespyl]: https://github.com/crespyl
|
|
451
|
+
[@thomasleplus]: https://github.com/thomasleplus
|
|
452
|
+
[@valdelaseras]: https://github.com/valdelaseras
|
|
443
453
|
|
|
444
454
|
[8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
|
|
445
455
|
[9a33498]: https://github.com/gchq/CyberChef/commit/9a33498fed26a8df9c9f35f39a78a174bf50a513
|
|
@@ -540,4 +550,6 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
540
550
|
[#1364]: https://github.com/gchq/CyberChef/pull/1364
|
|
541
551
|
[#1264]: https://github.com/gchq/CyberChef/pull/1264
|
|
542
552
|
[#1266]: https://github.com/gchq/CyberChef/pull/1266
|
|
553
|
+
[#1250]: https://github.com/gchq/CyberChef/pull/1250
|
|
554
|
+
[#1308]: https://github.com/gchq/CyberChef/pull/1308
|
|
543
555
|
|
package/README.md
CHANGED
|
@@ -54,7 +54,7 @@ You can use as many operations as you like in simple or complex ways. Some examp
|
|
|
54
54
|
- Whenever you modify the input or the recipe, CyberChef will automatically "bake" for you and produce the output immediately.
|
|
55
55
|
- This can be turned off and operated manually if it is affecting performance (if the input is very large, for instance).
|
|
56
56
|
- Automated encoding detection
|
|
57
|
-
- CyberChef uses [a number of techniques](https://github.com/gchq/CyberChef/wiki/Automatic-detection-of-encoded-data-using-CyberChef-Magic) to attempt to automatically detect which encodings your data is under. If it finds a suitable operation
|
|
57
|
+
- CyberChef uses [a number of techniques](https://github.com/gchq/CyberChef/wiki/Automatic-detection-of-encoded-data-using-CyberChef-Magic) to attempt to automatically detect which encodings your data is under. If it finds a suitable operation that make sense of your data, it displays the 'magic' icon in the Output field which you can click to decode your data.
|
|
58
58
|
- Breakpoints
|
|
59
59
|
- You can set breakpoints on any operation in your recipe to pause execution before running it.
|
|
60
60
|
- You can also step through the recipe one operation at a time to see what the data looks like at each stage.
|
|
@@ -66,7 +66,7 @@ You can use as many operations as you like in simple or complex ways. Some examp
|
|
|
66
66
|
- Highlighting
|
|
67
67
|
- When you highlight text in the input or output, the offset and length values will be displayed and, if possible, the corresponding data will be highlighted in the output or input respectively (example: [highlight the word 'question' in the input to see where it appears in the output][11]).
|
|
68
68
|
- Save to file and load from file
|
|
69
|
-
- You can save the output to a file at any time or load a file by dragging and dropping it into the input field. Files up to around 2GB are supported (depending on your browser), however some operations may take a very long time to run over this much data.
|
|
69
|
+
- You can save the output to a file at any time or load a file by dragging and dropping it into the input field. Files up to around 2GB are supported (depending on your browser), however, some operations may take a very long time to run over this much data.
|
|
70
70
|
- CyberChef is entirely client-side
|
|
71
71
|
- It should be noted that none of your recipe configuration or input (either text or files) is ever sent to the CyberChef web server - all processing is carried out within your browser, on your own computer.
|
|
72
72
|
- Due to this feature, CyberChef can be downloaded and run locally. You can use the link in the top left corner of the app to download a full copy of CyberChef and drop it into a virtual machine, share it with other people, or host it in a closed network.
|
|
@@ -74,10 +74,10 @@ You can use as many operations as you like in simple or complex ways. Some examp
|
|
|
74
74
|
|
|
75
75
|
## Deep linking
|
|
76
76
|
|
|
77
|
-
By
|
|
77
|
+
By manipulating CyberChef's URL hash, you can change the initial settings with which the page opens.
|
|
78
78
|
The format is `https://gchq.github.io/CyberChef/#recipe=Operation()&input=...`
|
|
79
79
|
|
|
80
|
-
Supported arguments are `recipe`, `input` (encoded in Base64), and `theme`.
|
|
80
|
+
Supported arguments are `recipe`, `input` (encoded in Base64), and `theme`.
|
|
81
81
|
|
|
82
82
|
|
|
83
83
|
## Browser support
|
|
@@ -90,12 +90,12 @@ CyberChef is built to support
|
|
|
90
90
|
|
|
91
91
|
## Node.js support
|
|
92
92
|
|
|
93
|
-
CyberChef is built to fully support Node.js `
|
|
93
|
+
CyberChef is built to fully support Node.js `v16`. For more information, see the Node API page in the project [wiki pages](https://github.com/gchq/CyberChef/wiki)
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
## Contributing
|
|
97
97
|
|
|
98
|
-
Contributing a new operation to CyberChef is super easy!
|
|
98
|
+
Contributing a new operation to CyberChef is super easy! The quickstart script will walk you through the process. If you can write basic JavaScript, you can write a CyberChef operation.
|
|
99
99
|
|
|
100
100
|
An installation walkthrough, how-to guides for adding new operations and themes, descriptions of the repository structure, available data types and coding conventions can all be found in the project [wiki pages](https://github.com/gchq/CyberChef/wiki).
|
|
101
101
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyberchef",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.46.2",
|
|
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",
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"js-sha3": "^0.8.0",
|
|
124
124
|
"jsesc": "^3.0.2",
|
|
125
125
|
"json5": "^2.2.1",
|
|
126
|
-
"jsonpath": "^
|
|
126
|
+
"jsonpath-plus": "^7.2.0",
|
|
127
127
|
"jsonwebtoken": "^8.5.1",
|
|
128
128
|
"jsqr": "^1.4.0",
|
|
129
129
|
"jsrsasign": "^10.5.23",
|
|
@@ -1506,6 +1506,33 @@
|
|
|
1506
1506
|
}
|
|
1507
1507
|
]
|
|
1508
1508
|
},
|
|
1509
|
+
"Cetacean Cipher Decode": {
|
|
1510
|
+
"module": "Ciphers",
|
|
1511
|
+
"description": "Decode Cetacean Cipher input. <br/><br/>e.g. <code>EEEEEEEEEeeEeEEEEEEEEEEEEeeEeEEe</code> becomes <code>hi</code>",
|
|
1512
|
+
"infoURL": "https://hitchhikers.fandom.com/wiki/Dolphins",
|
|
1513
|
+
"inputType": "string",
|
|
1514
|
+
"outputType": "string",
|
|
1515
|
+
"flowControl": false,
|
|
1516
|
+
"manualBake": false,
|
|
1517
|
+
"args": [],
|
|
1518
|
+
"checks": [
|
|
1519
|
+
{
|
|
1520
|
+
"pattern": "^(?:[eE]{16,})(?: [eE]{16,})*$",
|
|
1521
|
+
"flags": "",
|
|
1522
|
+
"args": []
|
|
1523
|
+
}
|
|
1524
|
+
]
|
|
1525
|
+
},
|
|
1526
|
+
"Cetacean Cipher Encode": {
|
|
1527
|
+
"module": "Ciphers",
|
|
1528
|
+
"description": "Converts any input into Cetacean Cipher. <br/><br/>e.g. <code>hi</code> becomes <code>EEEEEEEEEeeEeEEEEEEEEEEEEeeEeEEe</code>",
|
|
1529
|
+
"infoURL": "https://hitchhikers.fandom.com/wiki/Dolphins",
|
|
1530
|
+
"inputType": "string",
|
|
1531
|
+
"outputType": "string",
|
|
1532
|
+
"flowControl": false,
|
|
1533
|
+
"manualBake": false,
|
|
1534
|
+
"args": []
|
|
1535
|
+
},
|
|
1509
1536
|
"Change IP format": {
|
|
1510
1537
|
"module": "Default",
|
|
1511
1538
|
"description": "Convert an IP address from one format to another, e.g. <code>172.20.23.54</code> to <code>ac141736</code>",
|
|
@@ -7693,6 +7720,11 @@
|
|
|
7693
7720
|
"name": "Result delimiter",
|
|
7694
7721
|
"type": "binaryShortString",
|
|
7695
7722
|
"value": "\\n"
|
|
7723
|
+
},
|
|
7724
|
+
{
|
|
7725
|
+
"name": "Prevent eval",
|
|
7726
|
+
"type": "boolean",
|
|
7727
|
+
"value": true
|
|
7696
7728
|
}
|
|
7697
7729
|
]
|
|
7698
7730
|
},
|
|
@@ -17,6 +17,8 @@ import BifidCipherEncode from "../../operations/BifidCipherEncode.mjs";
|
|
|
17
17
|
import BlowfishDecrypt from "../../operations/BlowfishDecrypt.mjs";
|
|
18
18
|
import BlowfishEncrypt from "../../operations/BlowfishEncrypt.mjs";
|
|
19
19
|
import CaesarBoxCipher from "../../operations/CaesarBoxCipher.mjs";
|
|
20
|
+
import CetaceanCipherDecode from "../../operations/CetaceanCipherDecode.mjs";
|
|
21
|
+
import CetaceanCipherEncode from "../../operations/CetaceanCipherEncode.mjs";
|
|
20
22
|
import DESDecrypt from "../../operations/DESDecrypt.mjs";
|
|
21
23
|
import DESEncrypt from "../../operations/DESEncrypt.mjs";
|
|
22
24
|
import DeriveEVPKey from "../../operations/DeriveEVPKey.mjs";
|
|
@@ -55,6 +57,8 @@ OpModules.Ciphers = {
|
|
|
55
57
|
"Blowfish Decrypt": BlowfishDecrypt,
|
|
56
58
|
"Blowfish Encrypt": BlowfishEncrypt,
|
|
57
59
|
"Caesar Box Cipher": CaesarBoxCipher,
|
|
60
|
+
"Cetacean Cipher Decode": CetaceanCipherDecode,
|
|
61
|
+
"Cetacean Cipher Encode": CetaceanCipherEncode,
|
|
58
62
|
"DES Decrypt": DESDecrypt,
|
|
59
63
|
"DES Encrypt": DESEncrypt,
|
|
60
64
|
"Derive EVP key": DeriveEVPKey,
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author dolphinOnKeys [robin@weird.io]
|
|
3
|
+
* @copyright Crown Copyright 2022
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Cetacean Cipher Decode operation
|
|
11
|
+
*/
|
|
12
|
+
class CetaceanCipherDecode extends Operation {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* CetaceanCipherDecode constructor
|
|
16
|
+
*/
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
|
|
20
|
+
this.name = "Cetacean Cipher Decode";
|
|
21
|
+
this.module = "Ciphers";
|
|
22
|
+
this.description = "Decode Cetacean Cipher input. <br/><br/>e.g. <code>EEEEEEEEEeeEeEEEEEEEEEEEEeeEeEEe</code> becomes <code>hi</code>";
|
|
23
|
+
this.infoURL = "https://hitchhikers.fandom.com/wiki/Dolphins";
|
|
24
|
+
this.inputType = "string";
|
|
25
|
+
this.outputType = "string";
|
|
26
|
+
|
|
27
|
+
this.checks = [
|
|
28
|
+
{
|
|
29
|
+
pattern: "^(?:[eE]{16,})(?: [eE]{16,})*$",
|
|
30
|
+
flags: "",
|
|
31
|
+
args: []
|
|
32
|
+
}
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param {string} input
|
|
38
|
+
* @param {Object[]} args
|
|
39
|
+
* @returns {string}
|
|
40
|
+
*/
|
|
41
|
+
run(input, args) {
|
|
42
|
+
const binaryArray = [];
|
|
43
|
+
for (const char of input) {
|
|
44
|
+
if (char === " ") {
|
|
45
|
+
binaryArray.push(...[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]);
|
|
46
|
+
} else {
|
|
47
|
+
binaryArray.push(char === "e" ? 1 : 0);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const byteArray = [];
|
|
52
|
+
|
|
53
|
+
for (let i = 0; i < binaryArray.length; i += 16) {
|
|
54
|
+
byteArray.push(binaryArray.slice(i, i + 16).join(""));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return byteArray.map(byte =>
|
|
58
|
+
String.fromCharCode(parseInt(byte, 2))
|
|
59
|
+
).join("");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default CetaceanCipherDecode;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author dolphinOnKeys [robin@weird.io]
|
|
3
|
+
* @copyright Crown Copyright 2022
|
|
4
|
+
* @license Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import Operation from "../Operation.mjs";
|
|
8
|
+
import {toBinary} from "../lib/Binary.mjs";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Cetacean Cipher Encode operation
|
|
12
|
+
*/
|
|
13
|
+
class CetaceanCipherEncode extends Operation {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* CetaceanCipherEncode constructor
|
|
17
|
+
*/
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
|
|
21
|
+
this.name = "Cetacean Cipher Encode";
|
|
22
|
+
this.module = "Ciphers";
|
|
23
|
+
this.description = "Converts any input into Cetacean Cipher. <br/><br/>e.g. <code>hi</code> becomes <code>EEEEEEEEEeeEeEEEEEEEEEEEEeeEeEEe</code>";
|
|
24
|
+
this.infoURL = "https://hitchhikers.fandom.com/wiki/Dolphins";
|
|
25
|
+
this.inputType = "string";
|
|
26
|
+
this.outputType = "string";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {string} input
|
|
31
|
+
* @param {Object[]} args
|
|
32
|
+
* @returns {string}
|
|
33
|
+
*/
|
|
34
|
+
run(input, args) {
|
|
35
|
+
const result = [];
|
|
36
|
+
const charArray = input.split("");
|
|
37
|
+
|
|
38
|
+
charArray.map(character => {
|
|
39
|
+
if (character === " ") {
|
|
40
|
+
result.push(character);
|
|
41
|
+
} else {
|
|
42
|
+
const binaryArray = toBinary(character.charCodeAt(0), "None", 16).split("");
|
|
43
|
+
result.push(binaryArray.map(str => str === "1" ? "e" : "E").join(""));
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return result.join("");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default CetaceanCipherEncode;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @license Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import {JSONPath} from "jsonpath-plus";
|
|
8
8
|
import Operation from "../Operation.mjs";
|
|
9
9
|
import OperationError from "../errors/OperationError.mjs";
|
|
10
10
|
|
|
@@ -27,14 +27,20 @@ class JPathExpression extends Operation {
|
|
|
27
27
|
this.outputType = "string";
|
|
28
28
|
this.args = [
|
|
29
29
|
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
name: "Query",
|
|
31
|
+
type: "string",
|
|
32
|
+
value: ""
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
name: "Result delimiter",
|
|
36
|
+
type: "binaryShortString",
|
|
37
|
+
value: "\\n"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: "Prevent eval",
|
|
41
|
+
type: "boolean",
|
|
42
|
+
value: true,
|
|
43
|
+
description: "Evaluated expressions are disabled by default for security reasons"
|
|
38
44
|
}
|
|
39
45
|
];
|
|
40
46
|
}
|
|
@@ -45,18 +51,21 @@ class JPathExpression extends Operation {
|
|
|
45
51
|
* @returns {string}
|
|
46
52
|
*/
|
|
47
53
|
run(input, args) {
|
|
48
|
-
const [query, delimiter] = args;
|
|
49
|
-
let results,
|
|
50
|
-
obj;
|
|
54
|
+
const [query, delimiter, preventEval] = args;
|
|
55
|
+
let results, jsonObj;
|
|
51
56
|
|
|
52
57
|
try {
|
|
53
|
-
|
|
58
|
+
jsonObj = JSON.parse(input);
|
|
54
59
|
} catch (err) {
|
|
55
60
|
throw new OperationError(`Invalid input JSON: ${err.message}`);
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
try {
|
|
59
|
-
results =
|
|
64
|
+
results = JSONPath({
|
|
65
|
+
path: query,
|
|
66
|
+
json: jsonObj,
|
|
67
|
+
preventEval: preventEval
|
|
68
|
+
});
|
|
60
69
|
} catch (err) {
|
|
61
70
|
throw new OperationError(`Invalid JPath expression: ${err.message}`);
|
|
62
71
|
}
|
|
@@ -114,8 +114,11 @@ class JSONToCSV extends Operation {
|
|
|
114
114
|
* @returns {string}
|
|
115
115
|
*/
|
|
116
116
|
escapeCellContents(data, force=false) {
|
|
117
|
-
if (
|
|
118
|
-
|
|
117
|
+
if (data !== "string") {
|
|
118
|
+
const isPrimitive = data == null || typeof data !== "object";
|
|
119
|
+
if (isPrimitive) data = `${data}`;
|
|
120
|
+
else if (force) data = JSON.stringify(data);
|
|
121
|
+
}
|
|
119
122
|
|
|
120
123
|
// Double quotes should be doubled up
|
|
121
124
|
data = data.replace(/"/g, '""');
|
|
@@ -50,6 +50,8 @@ import CSVToJSON from "./CSVToJSON.mjs";
|
|
|
50
50
|
import CTPH from "./CTPH.mjs";
|
|
51
51
|
import CaesarBoxCipher from "./CaesarBoxCipher.mjs";
|
|
52
52
|
import CartesianProduct from "./CartesianProduct.mjs";
|
|
53
|
+
import CetaceanCipherDecode from "./CetaceanCipherDecode.mjs";
|
|
54
|
+
import CetaceanCipherEncode from "./CetaceanCipherEncode.mjs";
|
|
53
55
|
import ChangeIPFormat from "./ChangeIPFormat.mjs";
|
|
54
56
|
import ChiSquare from "./ChiSquare.mjs";
|
|
55
57
|
import CipherSaber2Decrypt from "./CipherSaber2Decrypt.mjs";
|
|
@@ -433,6 +435,8 @@ export {
|
|
|
433
435
|
CTPH,
|
|
434
436
|
CaesarBoxCipher,
|
|
435
437
|
CartesianProduct,
|
|
438
|
+
CetaceanCipherDecode,
|
|
439
|
+
CetaceanCipherEncode,
|
|
436
440
|
ChangeIPFormat,
|
|
437
441
|
ChiSquare,
|
|
438
442
|
CipherSaber2Decrypt,
|
package/src/node/index.mjs
CHANGED
|
@@ -60,6 +60,8 @@ import {
|
|
|
60
60
|
CTPH as core_CTPH,
|
|
61
61
|
CaesarBoxCipher as core_CaesarBoxCipher,
|
|
62
62
|
CartesianProduct as core_CartesianProduct,
|
|
63
|
+
CetaceanCipherDecode as core_CetaceanCipherDecode,
|
|
64
|
+
CetaceanCipherEncode as core_CetaceanCipherEncode,
|
|
63
65
|
ChangeIPFormat as core_ChangeIPFormat,
|
|
64
66
|
ChiSquare as core_ChiSquare,
|
|
65
67
|
CipherSaber2Decrypt as core_CipherSaber2Decrypt,
|
|
@@ -443,6 +445,8 @@ function generateChef() {
|
|
|
443
445
|
"CTPH": _wrap(core_CTPH),
|
|
444
446
|
"caesarBoxCipher": _wrap(core_CaesarBoxCipher),
|
|
445
447
|
"cartesianProduct": _wrap(core_CartesianProduct),
|
|
448
|
+
"cetaceanCipherDecode": _wrap(core_CetaceanCipherDecode),
|
|
449
|
+
"cetaceanCipherEncode": _wrap(core_CetaceanCipherEncode),
|
|
446
450
|
"changeIPFormat": _wrap(core_ChangeIPFormat),
|
|
447
451
|
"chiSquare": _wrap(core_ChiSquare),
|
|
448
452
|
"cipherSaber2Decrypt": _wrap(core_CipherSaber2Decrypt),
|
|
@@ -834,6 +838,8 @@ const CSVToJSON = chef.CSVToJSON;
|
|
|
834
838
|
const CTPH = chef.CTPH;
|
|
835
839
|
const caesarBoxCipher = chef.caesarBoxCipher;
|
|
836
840
|
const cartesianProduct = chef.cartesianProduct;
|
|
841
|
+
const cetaceanCipherDecode = chef.cetaceanCipherDecode;
|
|
842
|
+
const cetaceanCipherEncode = chef.cetaceanCipherEncode;
|
|
837
843
|
const changeIPFormat = chef.changeIPFormat;
|
|
838
844
|
const chiSquare = chef.chiSquare;
|
|
839
845
|
const cipherSaber2Decrypt = chef.cipherSaber2Decrypt;
|
|
@@ -1219,6 +1225,8 @@ const operations = [
|
|
|
1219
1225
|
CTPH,
|
|
1220
1226
|
caesarBoxCipher,
|
|
1221
1227
|
cartesianProduct,
|
|
1228
|
+
cetaceanCipherDecode,
|
|
1229
|
+
cetaceanCipherEncode,
|
|
1222
1230
|
changeIPFormat,
|
|
1223
1231
|
chiSquare,
|
|
1224
1232
|
cipherSaber2Decrypt,
|
|
@@ -1608,6 +1616,8 @@ export {
|
|
|
1608
1616
|
CTPH,
|
|
1609
1617
|
caesarBoxCipher,
|
|
1610
1618
|
cartesianProduct,
|
|
1619
|
+
cetaceanCipherDecode,
|
|
1620
|
+
cetaceanCipherEncode,
|
|
1611
1621
|
changeIPFormat,
|
|
1612
1622
|
chiSquare,
|
|
1613
1623
|
cipherSaber2Decrypt,
|
|
@@ -82,7 +82,17 @@ a:focus {
|
|
|
82
82
|
border-color: var(--btn-success-hover-border-colour);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
select.form-control
|
|
85
|
+
select.form-control,
|
|
86
|
+
select.form-control:focus {
|
|
87
|
+
background-color: var(--primary-background-colour) !important;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
select.form-control:focus {
|
|
91
|
+
transition: none !important;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
select.form-control:not([size]):not([multiple]),
|
|
95
|
+
select.custom-file-control:not([size]):not([multiple]) {
|
|
86
96
|
height: unset !important;
|
|
87
97
|
}
|
|
88
98
|
|
|
@@ -145,7 +155,8 @@ optgroup {
|
|
|
145
155
|
color: var(--primary-font-colour);
|
|
146
156
|
}
|
|
147
157
|
|
|
148
|
-
.table-bordered th,
|
|
158
|
+
.table-bordered th,
|
|
159
|
+
.table-bordered td {
|
|
149
160
|
border: 1px solid var(--table-border-colour);
|
|
150
161
|
}
|
|
151
162
|
|
|
@@ -172,7 +183,9 @@ optgroup {
|
|
|
172
183
|
color: var(--subtext-font-colour);
|
|
173
184
|
}
|
|
174
185
|
|
|
175
|
-
.nav-tabs>li>a.nav-link.active,
|
|
186
|
+
.nav-tabs>li>a.nav-link.active,
|
|
187
|
+
.nav-tabs>li>a.nav-link.active:focus,
|
|
188
|
+
.nav-tabs>li>a.nav-link.active:hover {
|
|
176
189
|
background-color: var(--secondary-background-colour);
|
|
177
190
|
border-color: var(--secondary-border-colour);
|
|
178
191
|
border-bottom-color: transparent;
|
|
@@ -183,7 +196,8 @@ optgroup {
|
|
|
183
196
|
border-color: var(--primary-border-colour);
|
|
184
197
|
}
|
|
185
198
|
|
|
186
|
-
.nav a.nav-link:focus,
|
|
199
|
+
.nav a.nav-link:focus,
|
|
200
|
+
.nav a.nav-link:hover {
|
|
187
201
|
background-color: var(--secondary-border-colour);
|
|
188
202
|
}
|
|
189
203
|
|
|
@@ -199,7 +213,8 @@ optgroup {
|
|
|
199
213
|
color: var(--primary-font-colour);
|
|
200
214
|
}
|
|
201
215
|
|
|
202
|
-
.dropdown-menu a:focus,
|
|
216
|
+
.dropdown-menu a:focus,
|
|
217
|
+
.dropdown-menu a:hover {
|
|
203
218
|
background-color: var(--secondary-background-colour);
|
|
204
219
|
color: var(--primary-font-colour);
|
|
205
220
|
}
|
|
@@ -28,6 +28,8 @@ import "./tests/Base85.mjs";
|
|
|
28
28
|
import "./tests/BitwiseOp.mjs";
|
|
29
29
|
import "./tests/ByteRepr.mjs";
|
|
30
30
|
import "./tests/CartesianProduct.mjs";
|
|
31
|
+
import "./tests/CetaceanCipherEncode.mjs";
|
|
32
|
+
import "./tests/CetaceanCipherDecode.mjs";
|
|
31
33
|
import "./tests/CharEnc.mjs";
|
|
32
34
|
import "./tests/ChangeIPFormat.mjs";
|
|
33
35
|
import "./tests/Charts.mjs";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CetaceanCipher Encode tests
|
|
3
|
+
*
|
|
4
|
+
* @author dolphinOnKeys
|
|
5
|
+
* @copyright Crown Copyright 2022
|
|
6
|
+
* @licence Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
9
|
+
|
|
10
|
+
TestRegister.addTests([
|
|
11
|
+
{
|
|
12
|
+
name: "Cetacean Cipher Decode",
|
|
13
|
+
input: "EEEEEEEEEeeEEEEe EEEEEEEEEeeEEEeE EEEEEEEEEeeEEEee EEeeEEEEEeeEEeee",
|
|
14
|
+
expectedOutput: "a b c で",
|
|
15
|
+
recipeConfig: [
|
|
16
|
+
{
|
|
17
|
+
op: "Cetacean Cipher Decode",
|
|
18
|
+
args: []
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
}
|
|
22
|
+
]);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CetaceanCipher Encode tests
|
|
3
|
+
*
|
|
4
|
+
* @author dolphinOnKeys
|
|
5
|
+
* @copyright Crown Copyright 2022
|
|
6
|
+
* @licence Apache-2.0
|
|
7
|
+
*/
|
|
8
|
+
import TestRegister from "../../lib/TestRegister.mjs";
|
|
9
|
+
|
|
10
|
+
TestRegister.addTests([
|
|
11
|
+
{
|
|
12
|
+
name: "Cetacean Cipher Encode",
|
|
13
|
+
input: "a b c で",
|
|
14
|
+
expectedOutput: "EEEEEEEEEeeEEEEe EEEEEEEEEeeEEEeE EEEEEEEEEeeEEEee EEeeEEEEEeeEEeee",
|
|
15
|
+
recipeConfig: [
|
|
16
|
+
{
|
|
17
|
+
op: "Cetacean Cipher Encode",
|
|
18
|
+
args: []
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
}
|
|
22
|
+
]);
|
|
@@ -185,11 +185,11 @@ TestRegister.addTests([
|
|
|
185
185
|
{
|
|
186
186
|
name: "JPath Expression: Empty expression",
|
|
187
187
|
input: JSON.stringify(JSON_TEST_DATA),
|
|
188
|
-
expectedOutput: "
|
|
188
|
+
expectedOutput: "",
|
|
189
189
|
recipeConfig: [
|
|
190
190
|
{
|
|
191
191
|
"op": "JPath expression",
|
|
192
|
-
"args": ["", "\n"]
|
|
192
|
+
"args": ["", "\n", true]
|
|
193
193
|
}
|
|
194
194
|
],
|
|
195
195
|
},
|
|
@@ -205,7 +205,7 @@ TestRegister.addTests([
|
|
|
205
205
|
recipeConfig: [
|
|
206
206
|
{
|
|
207
207
|
"op": "JPath expression",
|
|
208
|
-
"args": ["$.store.book[*].author", "\n"]
|
|
208
|
+
"args": ["$.store.book[*].author", "\n", true]
|
|
209
209
|
}
|
|
210
210
|
],
|
|
211
211
|
},
|
|
@@ -223,7 +223,7 @@ TestRegister.addTests([
|
|
|
223
223
|
recipeConfig: [
|
|
224
224
|
{
|
|
225
225
|
"op": "JPath expression",
|
|
226
|
-
"args": ["$..title", "\n"]
|
|
226
|
+
"args": ["$..title", "\n", true]
|
|
227
227
|
}
|
|
228
228
|
],
|
|
229
229
|
},
|
|
@@ -238,7 +238,7 @@ TestRegister.addTests([
|
|
|
238
238
|
recipeConfig: [
|
|
239
239
|
{
|
|
240
240
|
"op": "JPath expression",
|
|
241
|
-
"args": ["$.store.*", "\n"]
|
|
241
|
+
"args": ["$.store.*", "\n", true]
|
|
242
242
|
}
|
|
243
243
|
],
|
|
244
244
|
},
|
|
@@ -249,7 +249,7 @@ TestRegister.addTests([
|
|
|
249
249
|
recipeConfig: [
|
|
250
250
|
{
|
|
251
251
|
"op": "JPath expression",
|
|
252
|
-
"args": ["$..book[-1:]", "\n"]
|
|
252
|
+
"args": ["$..book[-1:]", "\n", true]
|
|
253
253
|
}
|
|
254
254
|
],
|
|
255
255
|
},
|
|
@@ -263,7 +263,7 @@ TestRegister.addTests([
|
|
|
263
263
|
recipeConfig: [
|
|
264
264
|
{
|
|
265
265
|
"op": "JPath expression",
|
|
266
|
-
"args": ["$..book[:2]", "\n"]
|
|
266
|
+
"args": ["$..book[:2]", "\n", true]
|
|
267
267
|
}
|
|
268
268
|
],
|
|
269
269
|
},
|
|
@@ -277,7 +277,7 @@ TestRegister.addTests([
|
|
|
277
277
|
recipeConfig: [
|
|
278
278
|
{
|
|
279
279
|
"op": "JPath expression",
|
|
280
|
-
"args": ["$..book[?(@.isbn)]", "\n"]
|
|
280
|
+
"args": ["$..book[?(@.isbn)]", "\n", false]
|
|
281
281
|
}
|
|
282
282
|
],
|
|
283
283
|
},
|
|
@@ -292,7 +292,7 @@ TestRegister.addTests([
|
|
|
292
292
|
recipeConfig: [
|
|
293
293
|
{
|
|
294
294
|
"op": "JPath expression",
|
|
295
|
-
"args": ["$..book[?(@.price<30 && @.category==\"fiction\")]", "\n"]
|
|
295
|
+
"args": ["$..book[?(@.price<30 && @.category==\"fiction\")]", "\n", false]
|
|
296
296
|
}
|
|
297
297
|
],
|
|
298
298
|
},
|
|
@@ -306,9 +306,24 @@ TestRegister.addTests([
|
|
|
306
306
|
recipeConfig: [
|
|
307
307
|
{
|
|
308
308
|
"op": "JPath expression",
|
|
309
|
-
"args": ["$..book[?(@.price<10)]", "\n"]
|
|
309
|
+
"args": ["$..book[?(@.price<10)]", "\n", false]
|
|
310
|
+
}
|
|
311
|
+
],
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
name: "JPath Expression: Script-based expression",
|
|
315
|
+
input: "[{}]",
|
|
316
|
+
recipeConfig: [
|
|
317
|
+
{
|
|
318
|
+
"op": "JPath expression",
|
|
319
|
+
"args": [
|
|
320
|
+
"$..[?(({__proto__:[].constructor}).constructor(\"self.postMessage({action:'bakeComplete',data:{bakeId:1,dish:{type:1,value:''},duration:1,error:false,id:undefined,inputNum:2,progress:1,result:'<iframe/onload=debugger>',type: 'html'}});\")();)]",
|
|
321
|
+
"\n",
|
|
322
|
+
true
|
|
323
|
+
]
|
|
310
324
|
}
|
|
311
325
|
],
|
|
326
|
+
expectedOutput: "Invalid JPath expression: Eval [?(expr)] prevented in JSONPath expression."
|
|
312
327
|
},
|
|
313
328
|
{
|
|
314
329
|
name: "CSS selector",
|
|
@@ -46,6 +46,17 @@ TestRegister.addTests([
|
|
|
46
46
|
},
|
|
47
47
|
],
|
|
48
48
|
},
|
|
49
|
+
{
|
|
50
|
+
name: "JSON to CSV: boolean and null as values",
|
|
51
|
+
input: JSON.stringify({a: false, b: null, c: 3}),
|
|
52
|
+
expectedOutput: "a,b,c\r\nfalse,null,3\r\n",
|
|
53
|
+
recipeConfig: [
|
|
54
|
+
{
|
|
55
|
+
op: "JSON to CSV",
|
|
56
|
+
args: [",", "\\r\\n"]
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
49
60
|
{
|
|
50
61
|
name: "JSON to CSV: JSON as an array",
|
|
51
62
|
input: JSON.stringify([{a: 1, b: "2", c: 3}]),
|