cyberchef 9.42.0 → 9.45.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 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.44.0] - 2022-07-08
17
+ - Added 'LZString Compress' and 'LZString Decompress' operations [@crespyl] | [#1266]
18
+
19
+ ### [9.43.0] - 2022-07-08
20
+ - Added 'ROT13 Brute Force' and 'ROT47 Brute Force' operations [@mikecat] | [#1264]
21
+
22
+ ### [9.42.0] - 2022-07-08
23
+ - Added 'LS47 Encrypt' and 'LS47 Decrypt' operations [@n1073645] | [#951]
24
+
16
25
  ### [9.41.0] - 2022-07-08
17
26
  - Added 'Caesar Box Cipher' operation [@n1073645] | [#1066]
18
27
 
@@ -300,6 +309,9 @@ All major and minor version changes will be documented in this file. Details of
300
309
 
301
310
 
302
311
 
312
+ [9.44.0]: https://github.com/gchq/CyberChef/releases/tag/v9.44.0
313
+ [9.43.0]: https://github.com/gchq/CyberChef/releases/tag/v9.43.0
314
+ [9.42.0]: https://github.com/gchq/CyberChef/releases/tag/v9.42.0
303
315
  [9.41.0]: https://github.com/gchq/CyberChef/releases/tag/v9.41.0
304
316
  [9.40.0]: https://github.com/gchq/CyberChef/releases/tag/v9.40.0
305
317
  [9.39.0]: https://github.com/gchq/CyberChef/releases/tag/v9.39.0
@@ -426,6 +438,8 @@ All major and minor version changes will be documented in this file. Details of
426
438
  [@t-8ch]: https://github.com/t-8ch
427
439
  [@hettysymes]: https://github.com/hettysymes
428
440
  [@swesven]: https://github.com/swesven
441
+ [@mikecat]: https://github.com/mikecat
442
+ [@crespyl]: https://github.com/crespyl
429
443
 
430
444
  [8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
431
445
  [9a33498]: https://github.com/gchq/CyberChef/commit/9a33498fed26a8df9c9f35f39a78a174bf50a513
@@ -504,6 +518,7 @@ All major and minor version changes will be documented in this file. Details of
504
518
  [#917]: https://github.com/gchq/CyberChef/pull/917
505
519
  [#934]: https://github.com/gchq/CyberChef/pull/934
506
520
  [#948]: https://github.com/gchq/CyberChef/pull/948
521
+ [#951]: https://github.com/gchq/CyberChef/pull/951
507
522
  [#952]: https://github.com/gchq/CyberChef/pull/952
508
523
  [#965]: https://github.com/gchq/CyberChef/pull/965
509
524
  [#966]: https://github.com/gchq/CyberChef/pull/966
@@ -523,3 +538,6 @@ All major and minor version changes will be documented in this file. Details of
523
538
  [#1313]: https://github.com/gchq/CyberChef/pull/1313
524
539
  [#1326]: https://github.com/gchq/CyberChef/pull/1326
525
540
  [#1364]: https://github.com/gchq/CyberChef/pull/1364
541
+ [#1264]: https://github.com/gchq/CyberChef/pull/1264
542
+ [#1266]: https://github.com/gchq/CyberChef/pull/1266
543
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyberchef",
3
- "version": "9.42.0",
3
+ "version": "9.45.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",
@@ -133,6 +133,7 @@
133
133
  "lodash": "^4.17.21",
134
134
  "loglevel": "^1.8.0",
135
135
  "loglevel-message-prefix": "^3.0.0",
136
+ "lz-string": "^1.4.4",
136
137
  "markdown-it": "^13.0.1",
137
138
  "moment": "^2.29.3",
138
139
  "moment-timezone": "^0.5.34",
@@ -88,7 +88,10 @@
88
88
  "SM4 Encrypt",
89
89
  "SM4 Decrypt",
90
90
  "ROT13",
91
+ "ROT13 Brute Force",
91
92
  "ROT47",
93
+ "ROT47 Brute Force",
94
+ "ROT8000",
92
95
  "XOR",
93
96
  "XOR Brute Force",
94
97
  "Vigenère Encode",
@@ -179,7 +182,8 @@
179
182
  "Bit shift right",
180
183
  "Rotate left",
181
184
  "Rotate right",
182
- "ROT13"
185
+ "ROT13",
186
+ "ROT8000"
183
187
  ]
184
188
  },
185
189
  {
@@ -323,7 +327,9 @@
323
327
  "Bzip2 Decompress",
324
328
  "Bzip2 Compress",
325
329
  "Tar",
326
- "Untar"
330
+ "Untar",
331
+ "LZString Compress",
332
+ "LZString Decompress"
327
333
  ]
328
334
  },
329
335
  {
@@ -7981,6 +7981,46 @@
7981
7981
  }
7982
7982
  ]
7983
7983
  },
7984
+ "LZString Compress": {
7985
+ "module": "Compression",
7986
+ "description": "Compress the input with lz-string.",
7987
+ "infoURL": "https://pieroxy.net/blog/pages/lz-string/index.html",
7988
+ "inputType": "string",
7989
+ "outputType": "string",
7990
+ "flowControl": false,
7991
+ "manualBake": false,
7992
+ "args": [
7993
+ {
7994
+ "name": "Compression Format",
7995
+ "type": "option",
7996
+ "value": [
7997
+ "default",
7998
+ "UTF16",
7999
+ "Base64"
8000
+ ]
8001
+ }
8002
+ ]
8003
+ },
8004
+ "LZString Decompress": {
8005
+ "module": "Compression",
8006
+ "description": "Decompresses data that was compressed with lz-string.",
8007
+ "infoURL": "https://pieroxy.net/blog/pages/lz-string/index.html",
8008
+ "inputType": "string",
8009
+ "outputType": "string",
8010
+ "flowControl": false,
8011
+ "manualBake": false,
8012
+ "args": [
8013
+ {
8014
+ "name": "Compression Format",
8015
+ "type": "option",
8016
+ "value": [
8017
+ "default",
8018
+ "UTF16",
8019
+ "Base64"
8020
+ ]
8021
+ }
8022
+ ]
8023
+ },
7984
8024
  "Label": {
7985
8025
  "module": "Default",
7986
8026
  "description": "Provides a location for conditional and fixed jumps to redirect execution to.",
@@ -10178,6 +10218,52 @@
10178
10218
  }
10179
10219
  ]
10180
10220
  },
10221
+ "ROT13 Brute Force": {
10222
+ "module": "Default",
10223
+ "description": "Try all meaningful amounts for ROT13.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.",
10224
+ "infoURL": "https://wikipedia.org/wiki/ROT13",
10225
+ "inputType": "byteArray",
10226
+ "outputType": "string",
10227
+ "flowControl": false,
10228
+ "manualBake": false,
10229
+ "args": [
10230
+ {
10231
+ "name": "Rotate lower case chars",
10232
+ "type": "boolean",
10233
+ "value": true
10234
+ },
10235
+ {
10236
+ "name": "Rotate upper case chars",
10237
+ "type": "boolean",
10238
+ "value": true
10239
+ },
10240
+ {
10241
+ "name": "Rotate numbers",
10242
+ "type": "boolean",
10243
+ "value": false
10244
+ },
10245
+ {
10246
+ "name": "Sample length",
10247
+ "type": "number",
10248
+ "value": 100
10249
+ },
10250
+ {
10251
+ "name": "Sample offset",
10252
+ "type": "number",
10253
+ "value": 0
10254
+ },
10255
+ {
10256
+ "name": "Print amount",
10257
+ "type": "boolean",
10258
+ "value": true
10259
+ },
10260
+ {
10261
+ "name": "Crib (known plaintext string)",
10262
+ "type": "string",
10263
+ "value": ""
10264
+ }
10265
+ ]
10266
+ },
10181
10267
  "ROT47": {
10182
10268
  "module": "Default",
10183
10269
  "description": "A slightly more complex variation of a caesar cipher, which includes ASCII characters from 33 '!' to 126 '~'. Default rotation: 47.",
@@ -10194,6 +10280,47 @@
10194
10280
  }
10195
10281
  ]
10196
10282
  },
10283
+ "ROT47 Brute Force": {
10284
+ "module": "Default",
10285
+ "description": "Try all meaningful amounts for ROT47.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.",
10286
+ "infoURL": "https://wikipedia.org/wiki/ROT13#Variants",
10287
+ "inputType": "byteArray",
10288
+ "outputType": "string",
10289
+ "flowControl": false,
10290
+ "manualBake": false,
10291
+ "args": [
10292
+ {
10293
+ "name": "Sample length",
10294
+ "type": "number",
10295
+ "value": 100
10296
+ },
10297
+ {
10298
+ "name": "Sample offset",
10299
+ "type": "number",
10300
+ "value": 0
10301
+ },
10302
+ {
10303
+ "name": "Print amount",
10304
+ "type": "boolean",
10305
+ "value": true
10306
+ },
10307
+ {
10308
+ "name": "Crib (known plaintext string)",
10309
+ "type": "string",
10310
+ "value": ""
10311
+ }
10312
+ ]
10313
+ },
10314
+ "ROT8000": {
10315
+ "module": "Default",
10316
+ "description": "The simple Caesar-cypher encryption that replaces each Unicode character with the one 0x8000 places forward or back along the alphabet.",
10317
+ "infoURL": "https://rot8000.com/info",
10318
+ "inputType": "string",
10319
+ "outputType": "string",
10320
+ "flowControl": false,
10321
+ "manualBake": false,
10322
+ "args": []
10323
+ },
10197
10324
  "RSA Decrypt": {
10198
10325
  "module": "Ciphers",
10199
10326
  "description": "Decrypt an RSA encrypted message with a PEM encoded private key.",
@@ -9,6 +9,8 @@ import Bzip2Compress from "../../operations/Bzip2Compress.mjs";
9
9
  import Bzip2Decompress from "../../operations/Bzip2Decompress.mjs";
10
10
  import Gunzip from "../../operations/Gunzip.mjs";
11
11
  import Gzip from "../../operations/Gzip.mjs";
12
+ import LZStringCompress from "../../operations/LZStringCompress.mjs";
13
+ import LZStringDecompress from "../../operations/LZStringDecompress.mjs";
12
14
  import RawDeflate from "../../operations/RawDeflate.mjs";
13
15
  import RawInflate from "../../operations/RawInflate.mjs";
14
16
  import Tar from "../../operations/Tar.mjs";
@@ -25,6 +27,8 @@ OpModules.Compression = {
25
27
  "Bzip2 Decompress": Bzip2Decompress,
26
28
  "Gunzip": Gunzip,
27
29
  "Gzip": Gzip,
30
+ "LZString Compress": LZStringCompress,
31
+ "LZString Decompress": LZStringDecompress,
28
32
  "Raw Deflate": RawDeflate,
29
33
  "Raw Inflate": RawInflate,
30
34
  "Tar": Tar,
@@ -107,7 +107,10 @@ import ParseUNIXFilePermissions from "../../operations/ParseUNIXFilePermissions.
107
107
  import PlayMedia from "../../operations/PlayMedia.mjs";
108
108
  import PowerSet from "../../operations/PowerSet.mjs";
109
109
  import ROT13 from "../../operations/ROT13.mjs";
110
+ import ROT13BruteForce from "../../operations/ROT13BruteForce.mjs";
110
111
  import ROT47 from "../../operations/ROT47.mjs";
112
+ import ROT47BruteForce from "../../operations/ROT47BruteForce.mjs";
113
+ import ROT8000 from "../../operations/ROT8000.mjs";
111
114
  import RemoveDiacritics from "../../operations/RemoveDiacritics.mjs";
112
115
  import RemoveLineNumbers from "../../operations/RemoveLineNumbers.mjs";
113
116
  import RemoveNullBytes from "../../operations/RemoveNullBytes.mjs";
@@ -277,7 +280,10 @@ OpModules.Default = {
277
280
  "Play Media": PlayMedia,
278
281
  "Power Set": PowerSet,
279
282
  "ROT13": ROT13,
283
+ "ROT13 Brute Force": ROT13BruteForce,
280
284
  "ROT47": ROT47,
285
+ "ROT47 Brute Force": ROT47BruteForce,
286
+ "ROT8000": ROT8000,
281
287
  "Remove Diacritics": RemoveDiacritics,
282
288
  "Remove line numbers": RemoveLineNumbers,
283
289
  "Remove null bytes": RemoveNullBytes,
@@ -0,0 +1,21 @@
1
+ /**
2
+ * lz-string exports.
3
+ *
4
+ * @author crespyl [peter@crespyl.net]
5
+ * @copyright Peter Jacobs 2021
6
+ * @license Apache-2.0
7
+ */
8
+
9
+ import LZString from "lz-string";
10
+
11
+ export const COMPRESSION_OUTPUT_FORMATS = ["default", "UTF16", "Base64"];
12
+ export const COMPRESSION_FUNCTIONS = {
13
+ "default": LZString.compress,
14
+ "UTF16": LZString.compressToUTF16,
15
+ "Base64": LZString.compressToBase64,
16
+ };
17
+ export const DECOMPRESSION_FUNCTIONS = {
18
+ "default": LZString.decompress,
19
+ "UTF16": LZString.decompressFromUTF16,
20
+ "Base64": LZString.decompressFromBase64,
21
+ };
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @author crespyl [peter@crespyl.net]
3
+ * @copyright Peter Jacobs 2021
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+ import OperationError from "../errors/OperationError.mjs";
9
+
10
+ import {COMPRESSION_OUTPUT_FORMATS, COMPRESSION_FUNCTIONS} from "../lib/LZString.mjs";
11
+
12
+ /**
13
+ * LZString Compress operation
14
+ */
15
+ class LZStringCompress extends Operation {
16
+
17
+ /**
18
+ * LZStringCompress constructor
19
+ */
20
+ constructor() {
21
+ super();
22
+
23
+ this.name = "LZString Compress";
24
+ this.module = "Compression";
25
+ this.description = "Compress the input with lz-string.";
26
+ this.infoURL = "https://pieroxy.net/blog/pages/lz-string/index.html";
27
+ this.inputType = "string";
28
+ this.outputType = "string";
29
+ this.args = [
30
+ {
31
+ name: "Compression Format",
32
+ type: "option",
33
+ defaultIndex: 0,
34
+ value: COMPRESSION_OUTPUT_FORMATS
35
+ }
36
+ ];
37
+ }
38
+
39
+ /**
40
+ * @param {string} input
41
+ * @param {Object[]} args
42
+ * @returns {string}
43
+ */
44
+ run(input, args) {
45
+ const compress = COMPRESSION_FUNCTIONS[args[0]];
46
+ if (compress) {
47
+ return compress(input);
48
+ } else {
49
+ throw new OperationError("Unable to find compression function");
50
+ }
51
+ }
52
+
53
+ }
54
+
55
+ export default LZStringCompress;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @author crespyl [peter@crespyl.net]
3
+ * @copyright Peter Jacobs 2021
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+ import OperationError from "../errors/OperationError.mjs";
9
+
10
+ import {COMPRESSION_OUTPUT_FORMATS, DECOMPRESSION_FUNCTIONS} from "../lib/LZString.mjs";
11
+
12
+ /**
13
+ * LZString Decompress operation
14
+ */
15
+ class LZStringDecompress extends Operation {
16
+
17
+ /**
18
+ * LZStringDecompress constructor
19
+ */
20
+ constructor() {
21
+ super();
22
+
23
+ this.name = "LZString Decompress";
24
+ this.module = "Compression";
25
+ this.description = "Decompresses data that was compressed with lz-string.";
26
+ this.infoURL = "https://pieroxy.net/blog/pages/lz-string/index.html";
27
+ this.inputType = "string";
28
+ this.outputType = "string";
29
+ this.args = [
30
+ {
31
+ name: "Compression Format",
32
+ type: "option",
33
+ defaultIndex: 0,
34
+ value: COMPRESSION_OUTPUT_FORMATS
35
+ }
36
+ ];
37
+ }
38
+
39
+ /**
40
+ * @param {string} input
41
+ * @param {Object[]} args
42
+ * @returns {string}
43
+ */
44
+ run(input, args) {
45
+ const decompress = DECOMPRESSION_FUNCTIONS[args[0]];
46
+ if (decompress) {
47
+ return decompress(input);
48
+ } else {
49
+ throw new OperationError("Unable to find decompression function");
50
+ }
51
+ }
52
+
53
+
54
+ }
55
+
56
+ export default LZStringDecompress;
@@ -0,0 +1,102 @@
1
+ /**
2
+ * @author MikeCAT
3
+ * @license Apache-2.0
4
+ */
5
+
6
+ import Operation from "../Operation.mjs";
7
+ import Utils from "../Utils.mjs";
8
+
9
+ /**
10
+ * ROT13 Brute Force operation.
11
+ */
12
+ class ROT13BruteForce extends Operation {
13
+
14
+ /**
15
+ * ROT13BruteForce constructor
16
+ */
17
+ constructor() {
18
+ super();
19
+
20
+ this.name = "ROT13 Brute Force";
21
+ this.module = "Default";
22
+ this.description = "Try all meaningful amounts for ROT13.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.";
23
+ this.infoURL = "https://wikipedia.org/wiki/ROT13";
24
+ this.inputType = "byteArray";
25
+ this.outputType = "string";
26
+ this.args = [
27
+ {
28
+ name: "Rotate lower case chars",
29
+ type: "boolean",
30
+ value: true
31
+ },
32
+ {
33
+ name: "Rotate upper case chars",
34
+ type: "boolean",
35
+ value: true
36
+ },
37
+ {
38
+ name: "Rotate numbers",
39
+ type: "boolean",
40
+ value: false
41
+ },
42
+ {
43
+ name: "Sample length",
44
+ type: "number",
45
+ value: 100
46
+ },
47
+ {
48
+ name: "Sample offset",
49
+ type: "number",
50
+ value: 0
51
+ },
52
+ {
53
+ name: "Print amount",
54
+ type: "boolean",
55
+ value: true
56
+ },
57
+ {
58
+ name: "Crib (known plaintext string)",
59
+ type: "string",
60
+ value: ""
61
+ }
62
+ ];
63
+ }
64
+
65
+ /**
66
+ * @param {byteArray} input
67
+ * @param {Object[]} args
68
+ * @returns {string}
69
+ */
70
+ run(input, args) {
71
+ const [rotateLower, rotateUpper, rotateNum, sampleLength, sampleOffset, printAmount, crib] = args;
72
+ const sample = input.slice(sampleOffset, sampleOffset + sampleLength);
73
+ const cribLower = crib.toLowerCase();
74
+ const lowerStart = "a".charCodeAt(0), upperStart = "A".charCodeAt(0), numStart = "0".charCodeAt(0);
75
+ const result = [];
76
+ for (let amount = 1; amount < 26; amount++) {
77
+ const rotated = sample.slice();
78
+ for (let i = 0; i < rotated.length; i++) {
79
+ if (rotateLower && lowerStart <= rotated[i] && rotated[i] < lowerStart + 26) {
80
+ rotated[i] = (rotated[i] - lowerStart + amount) % 26 + lowerStart;
81
+ } else if (rotateUpper && upperStart <= rotated[i] && rotated[i] < upperStart + 26) {
82
+ rotated[i] = (rotated[i] - upperStart + amount) % 26 + upperStart;
83
+ } else if (rotateNum && numStart <= rotated[i] && rotated[i] < numStart + 10) {
84
+ rotated[i] = (rotated[i] - numStart + amount) % 10 + numStart;
85
+ }
86
+ }
87
+ const rotatedString = Utils.byteArrayToUtf8(rotated);
88
+ if (rotatedString.toLowerCase().indexOf(cribLower) >= 0) {
89
+ const rotatedStringPrintable = Utils.printable(rotatedString, false);
90
+ if (printAmount) {
91
+ const amountStr = "Amount = " + (" " + amount).slice(-2) + ": ";
92
+ result.push(amountStr + rotatedStringPrintable);
93
+ } else {
94
+ result.push(rotatedStringPrintable);
95
+ }
96
+ }
97
+ }
98
+ return result.join("\n");
99
+ }
100
+ }
101
+
102
+ export default ROT13BruteForce;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * @author MikeCAT
3
+ * @license Apache-2.0
4
+ */
5
+
6
+ import Operation from "../Operation.mjs";
7
+ import Utils from "../Utils.mjs";
8
+
9
+ /**
10
+ * ROT47 Brute Force operation.
11
+ */
12
+ class ROT47BruteForce extends Operation {
13
+
14
+ /**
15
+ * ROT47BruteForce constructor
16
+ */
17
+ constructor() {
18
+ super();
19
+
20
+ this.name = "ROT47 Brute Force";
21
+ this.module = "Default";
22
+ this.description = "Try all meaningful amounts for ROT47.<br><br>Optionally you can enter your known plaintext (crib) to filter the result.";
23
+ this.infoURL = "https://wikipedia.org/wiki/ROT13#Variants";
24
+ this.inputType = "byteArray";
25
+ this.outputType = "string";
26
+ this.args = [
27
+ {
28
+ name: "Sample length",
29
+ type: "number",
30
+ value: 100
31
+ },
32
+ {
33
+ name: "Sample offset",
34
+ type: "number",
35
+ value: 0
36
+ },
37
+ {
38
+ name: "Print amount",
39
+ type: "boolean",
40
+ value: true
41
+ },
42
+ {
43
+ name: "Crib (known plaintext string)",
44
+ type: "string",
45
+ value: ""
46
+ }
47
+ ];
48
+ }
49
+
50
+ /**
51
+ * @param {byteArray} input
52
+ * @param {Object[]} args
53
+ * @returns {string}
54
+ */
55
+ run(input, args) {
56
+ const [sampleLength, sampleOffset, printAmount, crib] = args;
57
+ const sample = input.slice(sampleOffset, sampleOffset + sampleLength);
58
+ const cribLower = crib.toLowerCase();
59
+ const result = [];
60
+ for (let amount = 1; amount < 94; amount++) {
61
+ const rotated = sample.slice();
62
+ for (let i = 0; i < rotated.length; i++) {
63
+ if (33 <= rotated[i] && rotated[i] <= 126) {
64
+ rotated[i] = (rotated[i] - 33 + amount) % 94 + 33;
65
+ }
66
+ }
67
+ const rotatedString = Utils.byteArrayToUtf8(rotated);
68
+ if (rotatedString.toLowerCase().indexOf(cribLower) >= 0) {
69
+ const rotatedStringPrintable = Utils.printable(rotatedString, false);
70
+ if (printAmount) {
71
+ const amountStr = "Amount = " + (" " + amount).slice(-2) + ": ";
72
+ result.push(amountStr + rotatedStringPrintable);
73
+ } else {
74
+ result.push(rotatedStringPrintable);
75
+ }
76
+ }
77
+ }
78
+ return result.join("\n");
79
+ }
80
+ }
81
+
82
+ export default ROT47BruteForce;
@@ -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;
@@ -194,6 +194,8 @@ import Jump from "./Jump.mjs";
194
194
  import Keccak from "./Keccak.mjs";
195
195
  import LS47Decrypt from "./LS47Decrypt.mjs";
196
196
  import LS47Encrypt from "./LS47Encrypt.mjs";
197
+ import LZStringCompress from "./LZStringCompress.mjs";
198
+ import LZStringDecompress from "./LZStringDecompress.mjs";
197
199
  import Label from "./Label.mjs";
198
200
  import Lorenz from "./Lorenz.mjs";
199
201
  import LuhnChecksum from "./LuhnChecksum.mjs";
@@ -252,7 +254,10 @@ import RC4 from "./RC4.mjs";
252
254
  import RC4Drop from "./RC4Drop.mjs";
253
255
  import RIPEMD from "./RIPEMD.mjs";
254
256
  import ROT13 from "./ROT13.mjs";
257
+ import ROT13BruteForce from "./ROT13BruteForce.mjs";
255
258
  import ROT47 from "./ROT47.mjs";
259
+ import ROT47BruteForce from "./ROT47BruteForce.mjs";
260
+ import ROT8000 from "./ROT8000.mjs";
256
261
  import RSADecrypt from "./RSADecrypt.mjs";
257
262
  import RSAEncrypt from "./RSAEncrypt.mjs";
258
263
  import RSASign from "./RSASign.mjs";
@@ -572,6 +577,8 @@ export {
572
577
  Keccak,
573
578
  LS47Decrypt,
574
579
  LS47Encrypt,
580
+ LZStringCompress,
581
+ LZStringDecompress,
575
582
  Label,
576
583
  Lorenz,
577
584
  LuhnChecksum,
@@ -630,7 +637,10 @@ export {
630
637
  RC4Drop,
631
638
  RIPEMD,
632
639
  ROT13,
640
+ ROT13BruteForce,
633
641
  ROT47,
642
+ ROT47BruteForce,
643
+ ROT8000,
634
644
  RSADecrypt,
635
645
  RSAEncrypt,
636
646
  RSASign,
@@ -197,6 +197,8 @@ import {
197
197
  Keccak as core_Keccak,
198
198
  LS47Decrypt as core_LS47Decrypt,
199
199
  LS47Encrypt as core_LS47Encrypt,
200
+ LZStringCompress as core_LZStringCompress,
201
+ LZStringDecompress as core_LZStringDecompress,
200
202
  Lorenz as core_Lorenz,
201
203
  LuhnChecksum as core_LuhnChecksum,
202
204
  MD2 as core_MD2,
@@ -253,7 +255,10 @@ import {
253
255
  RC4Drop as core_RC4Drop,
254
256
  RIPEMD as core_RIPEMD,
255
257
  ROT13 as core_ROT13,
258
+ ROT13BruteForce as core_ROT13BruteForce,
256
259
  ROT47 as core_ROT47,
260
+ ROT47BruteForce as core_ROT47BruteForce,
261
+ ROT8000 as core_ROT8000,
257
262
  RSADecrypt as core_RSADecrypt,
258
263
  RSAEncrypt as core_RSAEncrypt,
259
264
  RSASign as core_RSASign,
@@ -575,6 +580,8 @@ function generateChef() {
575
580
  "keccak": _wrap(core_Keccak),
576
581
  "LS47Decrypt": _wrap(core_LS47Decrypt),
577
582
  "LS47Encrypt": _wrap(core_LS47Encrypt),
583
+ "LZStringCompress": _wrap(core_LZStringCompress),
584
+ "LZStringDecompress": _wrap(core_LZStringDecompress),
578
585
  "lorenz": _wrap(core_Lorenz),
579
586
  "luhnChecksum": _wrap(core_LuhnChecksum),
580
587
  "MD2": _wrap(core_MD2),
@@ -631,7 +638,10 @@ function generateChef() {
631
638
  "RC4Drop": _wrap(core_RC4Drop),
632
639
  "RIPEMD": _wrap(core_RIPEMD),
633
640
  "ROT13": _wrap(core_ROT13),
641
+ "ROT13BruteForce": _wrap(core_ROT13BruteForce),
634
642
  "ROT47": _wrap(core_ROT47),
643
+ "ROT47BruteForce": _wrap(core_ROT47BruteForce),
644
+ "ROT8000": _wrap(core_ROT8000),
635
645
  "RSADecrypt": _wrap(core_RSADecrypt),
636
646
  "RSAEncrypt": _wrap(core_RSAEncrypt),
637
647
  "RSASign": _wrap(core_RSASign),
@@ -968,6 +978,8 @@ const jump = chef.jump;
968
978
  const keccak = chef.keccak;
969
979
  const LS47Decrypt = chef.LS47Decrypt;
970
980
  const LS47Encrypt = chef.LS47Encrypt;
981
+ const LZStringCompress = chef.LZStringCompress;
982
+ const LZStringDecompress = chef.LZStringDecompress;
971
983
  const label = chef.label;
972
984
  const lorenz = chef.lorenz;
973
985
  const luhnChecksum = chef.luhnChecksum;
@@ -1026,7 +1038,10 @@ const RC4 = chef.RC4;
1026
1038
  const RC4Drop = chef.RC4Drop;
1027
1039
  const RIPEMD = chef.RIPEMD;
1028
1040
  const ROT13 = chef.ROT13;
1041
+ const ROT13BruteForce = chef.ROT13BruteForce;
1029
1042
  const ROT47 = chef.ROT47;
1043
+ const ROT47BruteForce = chef.ROT47BruteForce;
1044
+ const ROT8000 = chef.ROT8000;
1030
1045
  const RSADecrypt = chef.RSADecrypt;
1031
1046
  const RSAEncrypt = chef.RSAEncrypt;
1032
1047
  const RSASign = chef.RSASign;
@@ -1348,6 +1363,8 @@ const operations = [
1348
1363
  keccak,
1349
1364
  LS47Decrypt,
1350
1365
  LS47Encrypt,
1366
+ LZStringCompress,
1367
+ LZStringDecompress,
1351
1368
  label,
1352
1369
  lorenz,
1353
1370
  luhnChecksum,
@@ -1406,7 +1423,10 @@ const operations = [
1406
1423
  RC4Drop,
1407
1424
  RIPEMD,
1408
1425
  ROT13,
1426
+ ROT13BruteForce,
1409
1427
  ROT47,
1428
+ ROT47BruteForce,
1429
+ ROT8000,
1410
1430
  RSADecrypt,
1411
1431
  RSAEncrypt,
1412
1432
  RSASign,
@@ -1732,6 +1752,8 @@ export {
1732
1752
  keccak,
1733
1753
  LS47Decrypt,
1734
1754
  LS47Encrypt,
1755
+ LZStringCompress,
1756
+ LZStringDecompress,
1735
1757
  label,
1736
1758
  lorenz,
1737
1759
  luhnChecksum,
@@ -1790,7 +1812,10 @@ export {
1790
1812
  RC4Drop,
1791
1813
  RIPEMD,
1792
1814
  ROT13,
1815
+ ROT13BruteForce,
1793
1816
  ROT47,
1817
+ ROT47BruteForce,
1818
+ ROT8000,
1794
1819
  RSADecrypt,
1795
1820
  RSAEncrypt,
1796
1821
  RSASign,
@@ -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");
@@ -118,6 +118,7 @@ import "./tests/ELFInfo.mjs";
118
118
  import "./tests/Subsection.mjs";
119
119
  import "./tests/CaesarBoxCipher.mjs";
120
120
  import "./tests/LS47.mjs";
121
+ import "./tests/LZString.mjs";
121
122
 
122
123
 
123
124
  // Cannot test operations that use the File type yet
@@ -0,0 +1,33 @@
1
+ /**
2
+ * LZString tests.
3
+ *
4
+ * @author crespyl [peter@crespyl.net]
5
+ * @copyright Peter Jacobs 2021
6
+ * @license Apache-2.0
7
+ */
8
+ import TestRegister from "../../lib/TestRegister.mjs";
9
+
10
+ TestRegister.addTests([
11
+ {
12
+ name: "LZString Compress To Base64",
13
+ input: "hello world",
14
+ expectedOutput: "BYUwNmD2AEDukCcwBMg=",
15
+ recipeConfig: [
16
+ {
17
+ "op": "LZString Compress",
18
+ "args": ["Base64"]
19
+ }
20
+ ],
21
+ },
22
+ {
23
+ name: "LZString Decompress From Base64",
24
+ input: "BYUwNmD2AEDukCcwBMg=",
25
+ expectedOutput: "hello world",
26
+ recipeConfig: [
27
+ {
28
+ "op": "LZString Decompress",
29
+ "args": ["Base64"]
30
+ }
31
+ ],
32
+ }
33
+ ]);
@@ -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
  ]);