Преглед на файлове

Merge branch 'ROT8000' of https://github.com/thomasleplus/CyberChef

n1474335 преди 3 години
родител
ревизия
d99ee32cc4
променени са 4 файла, в които са добавени 142 реда и са изтрити 1 реда
  1. 3 1
      src/core/config/Categories.json
  2. 105 0
      src/core/operations/ROT8000.mjs
  3. 1 0
      tests/browser/ops.js
  4. 33 0
      tests/operations/tests/Rotate.mjs

+ 3 - 1
src/core/config/Categories.json

@@ -91,6 +91,7 @@
             "ROT13 Brute Force",
             "ROT13 Brute Force",
             "ROT47",
             "ROT47",
             "ROT47 Brute Force",
             "ROT47 Brute Force",
+            "ROT8000",
             "XOR",
             "XOR",
             "XOR Brute Force",
             "XOR Brute Force",
             "Vigenère Encode",
             "Vigenère Encode",
@@ -181,7 +182,8 @@
             "Bit shift right",
             "Bit shift right",
             "Rotate left",
             "Rotate left",
             "Rotate right",
             "Rotate right",
-            "ROT13"
+            "ROT13",
+            "ROT8000"
         ]
         ]
     },
     },
     {
     {

+ 105 - 0
src/core/operations/ROT8000.mjs

@@ -0,0 +1,105 @@
+/**
+ * @author Daniel Temkin [http://danieltemkin.com]
+ * @author Thomas Leplus [https://www.leplus.org]
+ * @copyright Crown Copyright 2021
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation.mjs";
+
+/**
+ * ROT8000 operation.
+ */
+class ROT8000 extends Operation {
+
+    /**
+     * ROT8000 constructor
+     */
+    constructor() {
+        super();
+        this.name = "ROT8000";
+        this.module = "Default";
+        this.description = "The simple Caesar-cypher encryption that replaces each Unicode character with the one 0x8000 places forward or back along the alphabet.";
+        this.infoURL = "https://github.com/rottytooth/rot8000";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        // Inspired from https://github.com/rottytooth/rot8000/blob/main/rot8000.js
+        // these come from the valid-code-point-transitions.json file generated from the c# proj
+        // this is done bc: 1) don't trust JS's understanging of surrogate pairs and 2) consistency with original rot8000
+        const validCodePoints = JSON.parse('{"33":true,"127":false,"161":true,"5760":false,"5761":true,"8192":false,"8203":true,"8232":false,"8234":true,"8239":false,"8240":true,"8287":false,"8288":true,"12288":false,"12289":true,"55296":false,"57344":true}');
+        const bmpSize = 0x10000;
+        const rotList = {}; // the mapping of char to rotated char
+        const hiddenBlocks = [];
+        let startBlock = 0;
+        for (const key in validCodePoints) {
+            if (Object.prototype.hasOwnProperty.call(validCodePoints, key)) {
+                if (validCodePoints[key] === true)
+                    hiddenBlocks.push({ start: startBlock, end: parseInt(key, 10) - 1 });
+                else
+                    startBlock = parseInt(key, 10);
+            }
+        }
+        const validIntList = []; // list of all valid chars
+        let currValid = false;
+        for (let i = 0; i < bmpSize; i++) {
+            if (validCodePoints[i] !== undefined) {
+                currValid = validCodePoints[i];
+            }
+            if (currValid) validIntList.push(i);
+        }
+        const rotateNum = Object.keys(validIntList).length / 2;
+        // go through every valid char and find its match
+        for (let i = 0; i < validIntList.length; i++) {
+            rotList[String.fromCharCode(validIntList[i])] =
+                String.fromCharCode(validIntList[(i + rotateNum) % (rotateNum * 2)]);
+        }
+        let output = "";
+        for (let count = 0; count < input.length; count++) {
+            // if it is not in the mappings list, just add it directly (no rotation)
+            if (rotList[input[count]] === undefined) {
+                output += input[count];
+                continue;
+            }
+            // otherwise, rotate it and add it to the string
+            output += rotList[input[count]];
+        }
+        return output;
+    }
+
+    /**
+     * Highlight ROT8000
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight ROT8000 in reverse
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlightReverse(pos, args) {
+        return pos;
+    }
+}
+
+export default ROT8000;

+ 1 - 0
tests/browser/ops.js

@@ -249,6 +249,7 @@ module.exports = {
         // testOp(browser, "RIPEMD", "test input", "test_output");
         // testOp(browser, "RIPEMD", "test input", "test_output");
         // testOp(browser, "ROT13", "test input", "test_output");
         // testOp(browser, "ROT13", "test input", "test_output");
         // testOp(browser, "ROT47", "test input", "test_output");
         // testOp(browser, "ROT47", "test input", "test_output");
+        // testOp(browser, "ROT8000", "test input", "test_output");
         // testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output");
         // testOp(browser, "Rail Fence Cipher Decode", "test input", "test_output");
         // testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output");
         // testOp(browser, "Rail Fence Cipher Encode", "test input", "test_output");
         // testOp(browser, "Randomize Colour Palette", "test input", "test_output");
         // testOp(browser, "Randomize Colour Palette", "test input", "test_output");

+ 33 - 0
tests/operations/tests/Rotate.mjs

@@ -212,4 +212,37 @@ TestRegister.addTests([
             },
             },
         ],
         ],
     },
     },
+    {
+        name: "ROT8000: nothing",
+        input: "",
+        expectedOutput: "",
+        recipeConfig: [
+            {
+                op: "ROT8000",
+                args: []
+            },
+        ],
+    },
+    {
+        name: "ROT8000: normal",
+        input: "The Quick Brown Fox Jumped Over The Lazy Dog.",
+        expectedOutput: "籝籱籮 籚籾籲籬籴 籋类籸粀籷 籏籸粁 籓籾籶籹籮籭 籘籿籮类 籝籱籮 籕籪粃粂 籍籸籰簷",
+        recipeConfig: [
+            {
+                op: "ROT8000",
+                args: []
+            },
+        ],
+    },
+    {
+        name: "ROT8000: backward",
+        input: "籝籱籮 籚籾籲籬籴 籋类籸粀籷 籏籸粁 籓籾籶籹籮籭 籘籿籮类 籝籱籮 籕籪粃粂 籍籸籰簷",
+        expectedOutput: "The Quick Brown Fox Jumped Over The Lazy Dog.",
+        recipeConfig: [
+            {
+                op: "ROT8000",
+                args: []
+            },
+        ],
+    },
 ]);
 ]);