cyberchef 9.44.0 → 9.46.1
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 +18 -0
- package/README.md +6 -6
- package/package.json +1 -1
- package/src/core/config/Categories.json +5 -1
- package/src/core/config/OperationConfig.json +37 -0
- package/src/core/config/modules/Ciphers.mjs +4 -0
- package/src/core/config/modules/Default.mjs +2 -0
- package/src/core/operations/CetaceanCipherDecode.mjs +63 -0
- package/src/core/operations/CetaceanCipherEncode.mjs +51 -0
- package/src/core/operations/JSONToCSV.mjs +5 -2
- package/src/core/operations/ROT8000.mjs +123 -0
- package/src/core/operations/index.mjs +6 -0
- package/src/node/index.mjs +15 -0
- package/src/web/stylesheets/utils/_overrides.css +20 -5
- package/tests/browser/ops.js +1 -0
- 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/JSONtoCSV.mjs +11 -0
- package/tests/operations/tests/Rotate.mjs +33 -0
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,15 @@ 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
|
+
|
|
22
|
+
### [9.44.0] - 2022-07-08
|
|
23
|
+
- Added 'LZString Compress' and 'LZString Decompress' operations [@crespyl] | [#1266]
|
|
24
|
+
|
|
16
25
|
### [9.43.0] - 2022-07-08
|
|
17
26
|
- Added 'ROT13 Brute Force' and 'ROT47 Brute Force' operations [@mikecat] | [#1264]
|
|
18
27
|
|
|
@@ -306,6 +315,9 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
306
315
|
|
|
307
316
|
|
|
308
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
|
|
320
|
+
[9.44.0]: https://github.com/gchq/CyberChef/releases/tag/v9.44.0
|
|
309
321
|
[9.43.0]: https://github.com/gchq/CyberChef/releases/tag/v9.43.0
|
|
310
322
|
[9.42.0]: https://github.com/gchq/CyberChef/releases/tag/v9.42.0
|
|
311
323
|
[9.41.0]: https://github.com/gchq/CyberChef/releases/tag/v9.41.0
|
|
@@ -435,6 +447,9 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
435
447
|
[@hettysymes]: https://github.com/hettysymes
|
|
436
448
|
[@swesven]: https://github.com/swesven
|
|
437
449
|
[@mikecat]: https://github.com/mikecat
|
|
450
|
+
[@crespyl]: https://github.com/crespyl
|
|
451
|
+
[@thomasleplus]: https://github.com/thomasleplus
|
|
452
|
+
[@valdelaseras]: https://github.com/valdelaseras
|
|
438
453
|
|
|
439
454
|
[8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
|
|
440
455
|
[9a33498]: https://github.com/gchq/CyberChef/commit/9a33498fed26a8df9c9f35f39a78a174bf50a513
|
|
@@ -534,4 +549,7 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
534
549
|
[#1326]: https://github.com/gchq/CyberChef/pull/1326
|
|
535
550
|
[#1364]: https://github.com/gchq/CyberChef/pull/1364
|
|
536
551
|
[#1264]: https://github.com/gchq/CyberChef/pull/1264
|
|
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
|
|
537
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.1",
|
|
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",
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
"ROT13 Brute Force",
|
|
92
92
|
"ROT47",
|
|
93
93
|
"ROT47 Brute Force",
|
|
94
|
+
"ROT8000",
|
|
94
95
|
"XOR",
|
|
95
96
|
"XOR Brute Force",
|
|
96
97
|
"Vigenère Encode",
|
|
@@ -111,6 +112,8 @@
|
|
|
111
112
|
"Atbash Cipher",
|
|
112
113
|
"CipherSaber2 Encrypt",
|
|
113
114
|
"CipherSaber2 Decrypt",
|
|
115
|
+
"Cetacean Cipher Encode",
|
|
116
|
+
"Cetacean Cipher Decode",
|
|
114
117
|
"Substitute",
|
|
115
118
|
"Derive PBKDF2 key",
|
|
116
119
|
"Derive EVP key",
|
|
@@ -181,7 +184,8 @@
|
|
|
181
184
|
"Bit shift right",
|
|
182
185
|
"Rotate left",
|
|
183
186
|
"Rotate right",
|
|
184
|
-
"ROT13"
|
|
187
|
+
"ROT13",
|
|
188
|
+
"ROT8000"
|
|
185
189
|
]
|
|
186
190
|
},
|
|
187
191
|
{
|
|
@@ -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>",
|
|
@@ -10311,6 +10338,16 @@
|
|
|
10311
10338
|
}
|
|
10312
10339
|
]
|
|
10313
10340
|
},
|
|
10341
|
+
"ROT8000": {
|
|
10342
|
+
"module": "Default",
|
|
10343
|
+
"description": "The simple Caesar-cypher encryption that replaces each Unicode character with the one 0x8000 places forward or back along the alphabet.",
|
|
10344
|
+
"infoURL": "https://rot8000.com/info",
|
|
10345
|
+
"inputType": "string",
|
|
10346
|
+
"outputType": "string",
|
|
10347
|
+
"flowControl": false,
|
|
10348
|
+
"manualBake": false,
|
|
10349
|
+
"args": []
|
|
10350
|
+
},
|
|
10314
10351
|
"RSA Decrypt": {
|
|
10315
10352
|
"module": "Ciphers",
|
|
10316
10353
|
"description": "Decrypt an RSA encrypted message with a PEM encoded private key.",
|
|
@@ -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,
|
|
@@ -110,6 +110,7 @@ import ROT13 from "../../operations/ROT13.mjs";
|
|
|
110
110
|
import ROT13BruteForce from "../../operations/ROT13BruteForce.mjs";
|
|
111
111
|
import ROT47 from "../../operations/ROT47.mjs";
|
|
112
112
|
import ROT47BruteForce from "../../operations/ROT47BruteForce.mjs";
|
|
113
|
+
import ROT8000 from "../../operations/ROT8000.mjs";
|
|
113
114
|
import RemoveDiacritics from "../../operations/RemoveDiacritics.mjs";
|
|
114
115
|
import RemoveLineNumbers from "../../operations/RemoveLineNumbers.mjs";
|
|
115
116
|
import RemoveNullBytes from "../../operations/RemoveNullBytes.mjs";
|
|
@@ -282,6 +283,7 @@ OpModules.Default = {
|
|
|
282
283
|
"ROT13 Brute Force": ROT13BruteForce,
|
|
283
284
|
"ROT47": ROT47,
|
|
284
285
|
"ROT47 Brute Force": ROT47BruteForce,
|
|
286
|
+
"ROT8000": ROT8000,
|
|
285
287
|
"Remove Diacritics": RemoveDiacritics,
|
|
286
288
|
"Remove line numbers": RemoveLineNumbers,
|
|
287
289
|
"Remove null bytes": RemoveNullBytes,
|
|
@@ -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;
|
|
@@ -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, '""');
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author Daniel Temkin [http://danieltemkin.com]
|
|
3
|
+
* @author Thomas Leplus [https://www.leplus.org]
|
|
4
|
+
* @copyright Crown Copyright 2021
|
|
5
|
+
* @license Apache-2.0
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import Operation from "../Operation.mjs";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* ROT8000 operation.
|
|
12
|
+
*/
|
|
13
|
+
class ROT8000 extends Operation {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* ROT8000 constructor
|
|
17
|
+
*/
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
this.name = "ROT8000";
|
|
21
|
+
this.module = "Default";
|
|
22
|
+
this.description = "The simple Caesar-cypher encryption that replaces each Unicode character with the one 0x8000 places forward or back along the alphabet.";
|
|
23
|
+
this.infoURL = "https://rot8000.com/info";
|
|
24
|
+
this.inputType = "string";
|
|
25
|
+
this.outputType = "string";
|
|
26
|
+
this.args = [];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @param {byteArray} input
|
|
31
|
+
* @param {Object[]} args
|
|
32
|
+
* @returns {byteArray}
|
|
33
|
+
*/
|
|
34
|
+
run(input, args) {
|
|
35
|
+
// Inspired from https://github.com/rottytooth/rot8000/blob/main/rot8000.js
|
|
36
|
+
// these come from the valid-code-point-transitions.json file generated from the c# proj
|
|
37
|
+
// this is done bc: 1) don't trust JS's understanging of surrogate pairs and 2) consistency with original rot8000
|
|
38
|
+
const validCodePoints = {
|
|
39
|
+
"33": true,
|
|
40
|
+
"127": false,
|
|
41
|
+
"161": true,
|
|
42
|
+
"5760": false,
|
|
43
|
+
"5761": true,
|
|
44
|
+
"8192": false,
|
|
45
|
+
"8203": true,
|
|
46
|
+
"8232": false,
|
|
47
|
+
"8234": true,
|
|
48
|
+
"8239": false,
|
|
49
|
+
"8240": true,
|
|
50
|
+
"8287": false,
|
|
51
|
+
"8288": true,
|
|
52
|
+
"12288": false,
|
|
53
|
+
"12289": true,
|
|
54
|
+
"55296": false,
|
|
55
|
+
"57344": true
|
|
56
|
+
};
|
|
57
|
+
const bmpSize = 0x10000;
|
|
58
|
+
const rotList = {}; // the mapping of char to rotated char
|
|
59
|
+
const hiddenBlocks = [];
|
|
60
|
+
let startBlock = 0;
|
|
61
|
+
for (const key in validCodePoints) {
|
|
62
|
+
if (Object.prototype.hasOwnProperty.call(validCodePoints, key)) {
|
|
63
|
+
if (validCodePoints[key] === true)
|
|
64
|
+
hiddenBlocks.push({ start: startBlock, end: parseInt(key, 10) - 1 });
|
|
65
|
+
else
|
|
66
|
+
startBlock = parseInt(key, 10);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const validIntList = []; // list of all valid chars
|
|
70
|
+
let currValid = false;
|
|
71
|
+
for (let i = 0; i < bmpSize; i++) {
|
|
72
|
+
if (validCodePoints[i] !== undefined) {
|
|
73
|
+
currValid = validCodePoints[i];
|
|
74
|
+
}
|
|
75
|
+
if (currValid) validIntList.push(i);
|
|
76
|
+
}
|
|
77
|
+
const rotateNum = Object.keys(validIntList).length / 2;
|
|
78
|
+
// go through every valid char and find its match
|
|
79
|
+
for (let i = 0; i < validIntList.length; i++) {
|
|
80
|
+
rotList[String.fromCharCode(validIntList[i])] =
|
|
81
|
+
String.fromCharCode(validIntList[(i + rotateNum) % (rotateNum * 2)]);
|
|
82
|
+
}
|
|
83
|
+
let output = "";
|
|
84
|
+
for (let count = 0; count < input.length; count++) {
|
|
85
|
+
// if it is not in the mappings list, just add it directly (no rotation)
|
|
86
|
+
if (rotList[input[count]] === undefined) {
|
|
87
|
+
output += input[count];
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
// otherwise, rotate it and add it to the string
|
|
91
|
+
output += rotList[input[count]];
|
|
92
|
+
}
|
|
93
|
+
return output;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Highlight ROT8000
|
|
98
|
+
*
|
|
99
|
+
* @param {Object[]} pos
|
|
100
|
+
* @param {number} pos[].start
|
|
101
|
+
* @param {number} pos[].end
|
|
102
|
+
* @param {Object[]} args
|
|
103
|
+
* @returns {Object[]} pos
|
|
104
|
+
*/
|
|
105
|
+
highlight(pos, args) {
|
|
106
|
+
return pos;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Highlight ROT8000 in reverse
|
|
111
|
+
*
|
|
112
|
+
* @param {Object[]} pos
|
|
113
|
+
* @param {number} pos[].start
|
|
114
|
+
* @param {number} pos[].end
|
|
115
|
+
* @param {Object[]} args
|
|
116
|
+
* @returns {Object[]} pos
|
|
117
|
+
*/
|
|
118
|
+
highlightReverse(pos, args) {
|
|
119
|
+
return pos;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export default ROT8000;
|
|
@@ -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";
|
|
@@ -257,6 +259,7 @@ import ROT13 from "./ROT13.mjs";
|
|
|
257
259
|
import ROT13BruteForce from "./ROT13BruteForce.mjs";
|
|
258
260
|
import ROT47 from "./ROT47.mjs";
|
|
259
261
|
import ROT47BruteForce from "./ROT47BruteForce.mjs";
|
|
262
|
+
import ROT8000 from "./ROT8000.mjs";
|
|
260
263
|
import RSADecrypt from "./RSADecrypt.mjs";
|
|
261
264
|
import RSAEncrypt from "./RSAEncrypt.mjs";
|
|
262
265
|
import RSASign from "./RSASign.mjs";
|
|
@@ -432,6 +435,8 @@ export {
|
|
|
432
435
|
CTPH,
|
|
433
436
|
CaesarBoxCipher,
|
|
434
437
|
CartesianProduct,
|
|
438
|
+
CetaceanCipherDecode,
|
|
439
|
+
CetaceanCipherEncode,
|
|
435
440
|
ChangeIPFormat,
|
|
436
441
|
ChiSquare,
|
|
437
442
|
CipherSaber2Decrypt,
|
|
@@ -639,6 +644,7 @@ export {
|
|
|
639
644
|
ROT13BruteForce,
|
|
640
645
|
ROT47,
|
|
641
646
|
ROT47BruteForce,
|
|
647
|
+
ROT8000,
|
|
642
648
|
RSADecrypt,
|
|
643
649
|
RSAEncrypt,
|
|
644
650
|
RSASign,
|
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,
|
|
@@ -258,6 +260,7 @@ import {
|
|
|
258
260
|
ROT13BruteForce as core_ROT13BruteForce,
|
|
259
261
|
ROT47 as core_ROT47,
|
|
260
262
|
ROT47BruteForce as core_ROT47BruteForce,
|
|
263
|
+
ROT8000 as core_ROT8000,
|
|
261
264
|
RSADecrypt as core_RSADecrypt,
|
|
262
265
|
RSAEncrypt as core_RSAEncrypt,
|
|
263
266
|
RSASign as core_RSASign,
|
|
@@ -442,6 +445,8 @@ function generateChef() {
|
|
|
442
445
|
"CTPH": _wrap(core_CTPH),
|
|
443
446
|
"caesarBoxCipher": _wrap(core_CaesarBoxCipher),
|
|
444
447
|
"cartesianProduct": _wrap(core_CartesianProduct),
|
|
448
|
+
"cetaceanCipherDecode": _wrap(core_CetaceanCipherDecode),
|
|
449
|
+
"cetaceanCipherEncode": _wrap(core_CetaceanCipherEncode),
|
|
445
450
|
"changeIPFormat": _wrap(core_ChangeIPFormat),
|
|
446
451
|
"chiSquare": _wrap(core_ChiSquare),
|
|
447
452
|
"cipherSaber2Decrypt": _wrap(core_CipherSaber2Decrypt),
|
|
@@ -640,6 +645,7 @@ function generateChef() {
|
|
|
640
645
|
"ROT13BruteForce": _wrap(core_ROT13BruteForce),
|
|
641
646
|
"ROT47": _wrap(core_ROT47),
|
|
642
647
|
"ROT47BruteForce": _wrap(core_ROT47BruteForce),
|
|
648
|
+
"ROT8000": _wrap(core_ROT8000),
|
|
643
649
|
"RSADecrypt": _wrap(core_RSADecrypt),
|
|
644
650
|
"RSAEncrypt": _wrap(core_RSAEncrypt),
|
|
645
651
|
"RSASign": _wrap(core_RSASign),
|
|
@@ -832,6 +838,8 @@ const CSVToJSON = chef.CSVToJSON;
|
|
|
832
838
|
const CTPH = chef.CTPH;
|
|
833
839
|
const caesarBoxCipher = chef.caesarBoxCipher;
|
|
834
840
|
const cartesianProduct = chef.cartesianProduct;
|
|
841
|
+
const cetaceanCipherDecode = chef.cetaceanCipherDecode;
|
|
842
|
+
const cetaceanCipherEncode = chef.cetaceanCipherEncode;
|
|
835
843
|
const changeIPFormat = chef.changeIPFormat;
|
|
836
844
|
const chiSquare = chef.chiSquare;
|
|
837
845
|
const cipherSaber2Decrypt = chef.cipherSaber2Decrypt;
|
|
@@ -1039,6 +1047,7 @@ const ROT13 = chef.ROT13;
|
|
|
1039
1047
|
const ROT13BruteForce = chef.ROT13BruteForce;
|
|
1040
1048
|
const ROT47 = chef.ROT47;
|
|
1041
1049
|
const ROT47BruteForce = chef.ROT47BruteForce;
|
|
1050
|
+
const ROT8000 = chef.ROT8000;
|
|
1042
1051
|
const RSADecrypt = chef.RSADecrypt;
|
|
1043
1052
|
const RSAEncrypt = chef.RSAEncrypt;
|
|
1044
1053
|
const RSASign = chef.RSASign;
|
|
@@ -1216,6 +1225,8 @@ const operations = [
|
|
|
1216
1225
|
CTPH,
|
|
1217
1226
|
caesarBoxCipher,
|
|
1218
1227
|
cartesianProduct,
|
|
1228
|
+
cetaceanCipherDecode,
|
|
1229
|
+
cetaceanCipherEncode,
|
|
1219
1230
|
changeIPFormat,
|
|
1220
1231
|
chiSquare,
|
|
1221
1232
|
cipherSaber2Decrypt,
|
|
@@ -1423,6 +1434,7 @@ const operations = [
|
|
|
1423
1434
|
ROT13BruteForce,
|
|
1424
1435
|
ROT47,
|
|
1425
1436
|
ROT47BruteForce,
|
|
1437
|
+
ROT8000,
|
|
1426
1438
|
RSADecrypt,
|
|
1427
1439
|
RSAEncrypt,
|
|
1428
1440
|
RSASign,
|
|
@@ -1604,6 +1616,8 @@ export {
|
|
|
1604
1616
|
CTPH,
|
|
1605
1617
|
caesarBoxCipher,
|
|
1606
1618
|
cartesianProduct,
|
|
1619
|
+
cetaceanCipherDecode,
|
|
1620
|
+
cetaceanCipherEncode,
|
|
1607
1621
|
changeIPFormat,
|
|
1608
1622
|
chiSquare,
|
|
1609
1623
|
cipherSaber2Decrypt,
|
|
@@ -1811,6 +1825,7 @@ export {
|
|
|
1811
1825
|
ROT13BruteForce,
|
|
1812
1826
|
ROT47,
|
|
1813
1827
|
ROT47BruteForce,
|
|
1828
|
+
ROT8000,
|
|
1814
1829
|
RSADecrypt,
|
|
1815
1830
|
RSAEncrypt,
|
|
1816
1831
|
RSASign,
|
|
@@ -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
|
}
|
package/tests/browser/ops.js
CHANGED
|
@@ -249,6 +249,7 @@ module.exports = {
|
|
|
249
249
|
// testOp(browser, "RIPEMD", "test input", "test_output");
|
|
250
250
|
// testOp(browser, "ROT13", "test input", "test_output");
|
|
251
251
|
// testOp(browser, "ROT47", "test input", "test_output");
|
|
252
|
+
// testOp(browser, "ROT8000", "test input", "test_output");
|
|
252
253
|
// testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output");
|
|
253
254
|
// testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output");
|
|
254
255
|
// testOp(browser, "Randomize Colour Palette", "test input", "test_output");
|
|
@@ -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
|
+
]);
|
|
@@ -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}]),
|
|
@@ -212,4 +212,37 @@ TestRegister.addTests([
|
|
|
212
212
|
},
|
|
213
213
|
],
|
|
214
214
|
},
|
|
215
|
+
{
|
|
216
|
+
name: "ROT8000: nothing",
|
|
217
|
+
input: "",
|
|
218
|
+
expectedOutput: "",
|
|
219
|
+
recipeConfig: [
|
|
220
|
+
{
|
|
221
|
+
op: "ROT8000",
|
|
222
|
+
args: []
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: "ROT8000: normal",
|
|
228
|
+
input: "The Quick Brown Fox Jumped Over The Lazy Dog.",
|
|
229
|
+
expectedOutput: "籝籱籮 籚籾籲籬籴 籋类籸粀籷 籏籸粁 籓籾籶籹籮籭 籘籿籮类 籝籱籮 籕籪粃粂 籍籸籰簷",
|
|
230
|
+
recipeConfig: [
|
|
231
|
+
{
|
|
232
|
+
op: "ROT8000",
|
|
233
|
+
args: []
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
name: "ROT8000: backward",
|
|
239
|
+
input: "籝籱籮 籚籾籲籬籴 籋类籸粀籷 籏籸粁 籓籾籶籹籮籭 籘籿籮类 籝籱籮 籕籪粃粂 籍籸籰簷",
|
|
240
|
+
expectedOutput: "The Quick Brown Fox Jumped Over The Lazy Dog.",
|
|
241
|
+
recipeConfig: [
|
|
242
|
+
{
|
|
243
|
+
op: "ROT8000",
|
|
244
|
+
args: []
|
|
245
|
+
},
|
|
246
|
+
],
|
|
247
|
+
},
|
|
215
248
|
]);
|