فهرست منبع

Merge branch 'debruijn' of https://github.com/GCHQ77703/CyberChef

n1474335 2 سال پیش
والد
کامیت
0a0217cb66

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

@@ -490,6 +490,7 @@
             "P-list Viewer",
             "Disassemble x86",
             "Pseudo-Random Number Generator",
+            "Generate De Bruijn Sequence",
             "Generate UUID",
             "Generate TOTP",
             "Generate HOTP",

+ 87 - 0
src/core/operations/GenerateDeBruijnSequence.mjs

@@ -0,0 +1,87 @@
+/**
+ * @author gchq77703 [gchq77703@gchq.gov.uk]
+ * @copyright Crown Copyright 2019
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import OperationError from "../errors/OperationError";
+
+/**
+ * Generate De Bruijn Sequence operation
+ */
+class GenerateDeBruijnSequence extends Operation {
+
+    /**
+     * GenerateDeBruijnSequence constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Generate De Bruijn Sequence";
+        this.module = "Default";
+        this.description = "Generates rolling keycode combinations given a certain alphabet size and key length.";
+        this.infoURL = "https://wikipedia.org/wiki/De_Bruijn_sequence";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                name: "Alphabet size (k)",
+                type: "number",
+                value: 2
+            },
+            {
+                name: "Key length (n)",
+                type: "number",
+                value: 3
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const [k, n] = args;
+
+        if (k < 2 || k > 9) {
+            throw new OperationError("Invalid alphabet size, required to be between 2 and 9 (inclusive).");
+        }
+
+        if (n < 2) {
+            throw new OperationError("Invalid key length, required to be at least 2.");
+        }
+
+        if (Math.pow(k, n) > 50000) {
+            throw new OperationError("Too many permutations, please reduce k^n to under 50,000.");
+        }
+
+        const a = [];
+        for (let i = 0; i < k * n; i++) a.push(0);
+
+        const sequence = [];
+
+        (function db(t = 1, p = 1) {
+            if (t > n) {
+                if (n % p !== 0) return;
+                for (let j = 1; j <= p; j++) {
+                    sequence.push(a[j]);
+                }
+                return;
+            }
+
+            a[t] = a[t - p];
+            db(t + 1, p);
+            for (let j = a[t - p] + 1; j < k; j++) {
+                a[t] = j;
+                db(t + 1, t);
+            }
+        })();
+
+        return sequence.join("");
+    }
+}
+
+export default GenerateDeBruijnSequence;

+ 1 - 0
tests/operations/index.mjs

@@ -133,6 +133,7 @@ import "./tests/Rabbit.mjs";
 import "./tests/LevenshteinDistance.mjs";
 import "./tests/SwapCase.mjs";
 import "./tests/HKDF.mjs";
+import "./tests/GenerateDeBruijnSequence.mjs";
 
 // Cannot test operations that use the File type yet
 // import "./tests/SplitColourChannels.mjs";

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

@@ -0,0 +1,33 @@
+/**
+ * De Brujin Sequence tests.
+ *
+ * @author gchq77703 [gchq77703@gchq.gov.uk]
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+import TestRegister from "../TestRegister";
+
+TestRegister.addTests([
+    {
+        name: "Small Sequence",
+        input: "",
+        expectedOutput: "00010111",
+        recipeConfig: [
+            {
+                "op": "Generate De Bruijn Sequence",
+                "args": [2, 3]
+            }
+        ]
+    },
+    {
+        name: "Long Sequence",
+        input: "",
+        expectedOutput: "0000010000200003000110001200013000210002200023000310003200033001010010200103001110011200113001210012200123001310013200133002010020200203002110021200213002210022200223002310023200233003010030200303003110031200313003210032200323003310033200333010110101201013010210102201023010310103201033011020110301111011120111301121011220112301131011320113301202012030121101212012130122101222012230123101232012330130201303013110131201313013210132201323013310133201333020210202202023020310203202033021030211102112021130212102122021230213102132021330220302211022120221302221022220222302231022320223302303023110231202313023210232202323023310233202333030310303203033031110311203113031210312203123031310313203133032110321203213032210322203223032310323203233033110331203313033210332203323033310333203333111112111131112211123111321113311212112131122211223112321123311312113131132211323113321133312122121231213212133122131222212223122321223312313123221232312332123331313213133132221322313232132331332213323133321333322222322233223232233323233233333",
+        recipeConfig: [
+            {
+                "op": "Generate De Bruijn Sequence",
+                "args": [4, 5]
+            }
+        ]
+    }
+]);