Browse Source

Converted Bifid & moved over tests

Matt C 7 years ago
parent
commit
789ec94eff

+ 20 - 0
src/core/lib/Ciphers.mjs

@@ -39,3 +39,23 @@ export function affineEncode(input, args) {
     }
     return output;
 }
+
+/**
+ * Generates a polybius square for the given keyword
+ *
+ * @private
+ * @author Matt C [matt@artemisbot.uk]
+ * @param {string} keyword - Must be upper case
+ * @returns {string}
+ */
+export function genPolybiusSquare (keyword) {
+    const alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ",
+        polArray = `${keyword}${alpha}`.split("").unique(),
+        polybius = [];
+
+    for (let i = 0; i < 5; i++) {
+        polybius[i] = polArray.slice(i*5, i*5 + 5);
+    }
+
+    return polybius;
+}

+ 124 - 0
src/core/operations/BifidCipherDecode.mjs

@@ -0,0 +1,124 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import { genPolybiusSquare } from "../lib/Ciphers";
+
+/**
+ * Bifid Cipher Decode operation
+ */
+class BifidCipherDecode extends Operation {
+
+    /**
+     * BifidCipherDecode constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Bifid Cipher Decode";
+        this.module = "Ciphers";
+        this.description = "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "Keyword",
+                "type": "string",
+                "value": ""
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const keywordStr = args[0].toUpperCase().replace("J", "I"),
+            keyword = keywordStr.split("").unique(),
+            alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ",
+            structure = [];
+
+        let output = "",
+            count = 0,
+            trans = "";
+
+        if (keyword.length > 25)
+            return "The alphabet keyword must be less than 25 characters.";
+
+        if (!/^[a-zA-Z]+$/.test(keywordStr) && keyword.length > 0)
+            return "The key must consist only of letters";
+
+        const polybius = genPolybiusSquare(keywordStr);
+
+        input.replace("J", "I").split("").forEach((letter) => {
+            const alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0;
+            let polInd;
+
+            if (alpInd) {
+                for (let i = 0; i < 5; i++) {
+                    polInd = polybius[i].indexOf(letter.toLocaleUpperCase());
+                    if (polInd >= 0) {
+                        trans += `${i}${polInd}`;
+                    }
+                }
+
+                if (alpha.split("").indexOf(letter) >= 0) {
+                    structure.push(true);
+                } else if (alpInd) {
+                    structure.push(false);
+                }
+            } else {
+                structure.push(letter);
+            }
+        });
+
+        structure.forEach(pos => {
+            if (typeof pos === "boolean") {
+                const coords = [trans[count], trans[count+trans.length/2]];
+
+                output += pos ?
+                    polybius[coords[0]][coords[1]] :
+                    polybius[coords[0]][coords[1]].toLocaleLowerCase();
+                count++;
+            } else {
+                output += pos;
+            }
+        });
+
+        return output;
+    }
+
+    /**
+     * Highlight Bifid Cipher Decode
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight Bifid Cipher Decode 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 BifidCipherDecode;

+ 128 - 0
src/core/operations/BifidCipherEncode.mjs

@@ -0,0 +1,128 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import { genPolybiusSquare } from "../lib/Ciphers";
+
+/**
+ * Bifid Cipher Encode operation
+ */
+class BifidCipherEncode extends Operation {
+
+    /**
+     * BifidCipherEncode constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Bifid Cipher Encode";
+        this.module = "Ciphers";
+        this.description = "The Bifid cipher is a cipher which uses a Polybius square in conjunction with transposition, which can be fairly difficult to decipher without knowing the alphabet keyword.";
+        this.inputType = "string";
+        this.outputType = "string";
+        this.args = [
+            {
+                "name": "Keyword",
+                "type": "string",
+                "value": ""
+            }
+        ];
+    }
+
+    /**
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    run(input, args) {
+        const keywordStr = args[0].toUpperCase().replace("J", "I"),
+            keyword = keywordStr.split("").unique(),
+            alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ",
+            xCo = [],
+            yCo = [],
+            structure = [];
+
+        let output = "",
+            count = 0;
+
+        if (keyword.length > 25)
+            return "The alphabet keyword must be less than 25 characters.";
+
+        if (!/^[a-zA-Z]+$/.test(keywordStr) && keyword.length > 0)
+            return "The key must consist only of letters";
+
+        const polybius = genPolybiusSquare(keywordStr);
+
+        input.replace("J", "I").split("").forEach(letter => {
+            const alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0;
+            let polInd;
+
+            if (alpInd) {
+                for (let i = 0; i < 5; i++) {
+                    polInd = polybius[i].indexOf(letter.toLocaleUpperCase());
+                    if (polInd >= 0) {
+                        xCo.push(polInd);
+                        yCo.push(i);
+                    }
+                }
+
+                if (alpha.split("").indexOf(letter) >= 0) {
+                    structure.push(true);
+                } else if (alpInd) {
+                    structure.push(false);
+                }
+            } else {
+                structure.push(letter);
+            }
+        });
+
+        const trans = `${yCo.join("")}${xCo.join("")}`;
+
+        structure.forEach(pos => {
+            if (typeof pos === "boolean") {
+                const coords = trans.substr(2*count, 2).split("");
+
+                output += pos ?
+                    polybius[coords[0]][coords[1]] :
+                    polybius[coords[0]][coords[1]].toLocaleLowerCase();
+                count++;
+            } else {
+                output += pos;
+            }
+        });
+
+        return output;
+    }
+
+    /**
+     * Highlight Bifid Cipher Encode
+     *
+     * @param {Object[]} pos
+     * @param {number} pos[].start
+     * @param {number} pos[].end
+     * @param {Object[]} args
+     * @returns {Object[]} pos
+     */
+    highlight(pos, args) {
+        return pos;
+    }
+
+    /**
+     * Highlight Bifid Cipher Encode 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 BifidCipherEncode;

+ 66 - 0
test/tests/operations/Ciphers.mjs

@@ -99,4 +99,70 @@ TestRegister.addTests([
             }
         ],
     },
+    {
+        name: "Bifid Cipher Encode: no input",
+        input: "",
+        expectedOutput: "",
+        recipeConfig: [
+            {
+                "op": "Bifid Cipher Encode",
+                "args": ["nothing"]
+            }
+        ],
+    },
+    {
+        name: "Bifid Cipher Encode: no key",
+        input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
+        expectedOutput: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.",
+        recipeConfig: [
+            {
+                "op": "Bifid Cipher Encode",
+                "args": [""]
+            }
+        ],
+    },
+    {
+        name: "Bifid Cipher Encode: normal",
+        input: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
+        expectedOutput: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.",
+        recipeConfig: [
+            {
+                "op": "Bifid Cipher Encode",
+                "args": ["Schrodinger"]
+            }
+        ],
+    },
+    {
+        name: "Bifid Cipher Decode: no input",
+        input: "",
+        expectedOutput: "",
+        recipeConfig: [
+            {
+                "op": "Bifid Cipher Decode",
+                "args": ["nothing"]
+            }
+        ],
+    },
+    {
+        name: "Bifid Cipher Decode: no key",
+        input: "Vq daqcliho rmltofvlnc qbdhlcr nt qdq Fbm-Rdkkm vuoottnoi aitp al axf tdtmvt owppkaodtx.",
+        expectedOutput: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
+        recipeConfig: [
+            {
+                "op": "Bifid Cipher Decode",
+                "args": [""]
+            }
+        ],
+    },
+    {
+        name: "Bifid Cipher Decode: normal",
+        input: "Wc snpsigdd cpfrrcxnfi hikdnnp dm crc Fcb-Pdeug vueageacc vtyl sa zxm crebzp lyoeuaiwpv.",
+        expectedOutput: "We recreate conditions similar to the Van-Allen radiation belt in our secure facilities.",
+        recipeConfig: [
+            {
+                "op": "Bifid Cipher Decode",
+                "args": ["Schrodinger"]
+            }
+        ],
+    },
 ]);