Quellcode durchsuchen

Added Bifid Cipher Encode & Decode

Bifid Cipher + Tests
Matt C vor 8 Jahren
Ursprung
Commit
91c6f682e7

+ 2 - 0
src/core/config/Categories.js

@@ -89,6 +89,8 @@ const Categories = [
             "Vigenère Decode",
             "To Morse Code",
             "From Morse Code",
+            "Bifid Cipher Encode",
+            "Bifid Cipher Decode",
             "Affine Cipher Encode",
             "Affine Cipher Decode",
             "Atbash Cipher",

+ 30 - 0
src/core/config/OperationConfig.js

@@ -1512,6 +1512,36 @@ const OperationConfig = {
             }
         ]
     },
+    "Bifid Cipher Encode": {
+        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.",
+        run: Cipher.runBifidEnc,
+        highlight: true,
+        highlightReverse: true,
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Alphabet Key",
+                type: "string",
+                value: ""
+            }
+        ]
+    },
+    "Bifid Cipher Decode": {
+        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.",
+        run: Cipher.runBifidDec,
+        highlight: true,
+        highlightReverse: true,
+        inputType: "string",
+        outputType: "string",
+        args: [
+            {
+                name: "Alphabet Key",
+                type: "string",
+                value: ""
+            }
+        ]
+    },
     "Affine Cipher Encode": {
         description: "The Affine cipher is a type of monoalphabetic substitution cipher, wherein each letter in an alphabet is mapped to its numeric equivalent, encrypted using simple mathematical function, <code>(ax + b) % 26</code>, and converted back to a letter.",
         run: Cipher.runAffineEnc,

+ 137 - 6
src/core/operations/Cipher.js

@@ -407,7 +407,7 @@ const Cipher = {
     /**
      * Vigenère Encode operation.
      *
-     * @author Matt C [matt@artemisbot.pw]
+     * @author Matt C [matt@artemisbot.uk]
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
@@ -454,7 +454,7 @@ const Cipher = {
     /**
      * Vigenère Decode operation.
      *
-     * @author Matt C [matt@artemisbot.pw]
+     * @author Matt C [matt@artemisbot.uk]
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
@@ -508,7 +508,7 @@ const Cipher = {
     /**
      * Affine Cipher Encode operation.
      *
-     * @author Matt C [matt@artemisbot.pw]
+     * @author Matt C [matt@artemisbot.uk]
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
@@ -540,9 +540,9 @@ const Cipher = {
 
 
     /**
-     * Affine Cipher Encode operation.
+     * Affine Cipher Decode operation.
      *
-     * @author Matt C [matt@artemisbot.pw]
+     * @author Matt C [matt@artemisbot.uk]
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
@@ -584,7 +584,7 @@ const Cipher = {
     /**
      * Atbash Cipher Encode operation.
      *
-     * @author Matt C [matt@artemisbot.pw]
+     * @author Matt C [matt@artemisbot.uk]
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
@@ -593,6 +593,137 @@ const Cipher = {
         return Cipher.runAffineEnc(input, [25, 25]);
     },
 
+    /**
+     * Generates a polybius square for the given keyword
+     *
+     * @author Matt C [matt@artemisbot.uk]
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    genPolybiusSquare: function (keyword) {
+        const alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
+        let polybius = [],
+            polString = "";
+        keyword.split("").unique().forEach(letter => {
+            polString += letter;
+        });
+        polString = `${polString}${alpha}`.split("").unique().join("");
+        for (let i = 0; i < 5; i++) {
+            polybius[i] = polString.substr(i*5, 5).split("");
+        }
+        return polybius;
+    },
+
+    /**
+     * Bifid Cipher Encode operation
+     *
+     * @author Matt C [matt@artemisbot.uk]
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runBifidEnc: function (input, args) {
+        const keyword = args[0].toUpperCase().replace("J", "I"),
+            alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
+        let output = "",
+            xCo = [],
+            yCo = [],
+            structure = [],
+            count = 0,
+            trans;
+        if (keyword.split("").unique().length > 25) return "The alphabet keyword must be less than 25 characters.";
+        if (!/^[a-zA-Z]+$/.test(keyword) && keyword.split("").unique().length > 0) return "The key must consist only of letters";
+        const polybius = Cipher.genPolybiusSquare(keyword);
+        input.replace("J", "I").split("").forEach((letter) => {
+            let alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0,
+                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);
+            }
+        });
+        trans = `${yCo.join("")}${xCo.join("")}`;
+        structure.forEach(pos => {
+            if (typeof pos === "boolean") {
+                let coords = trans.substr(2*count, 2).split("");
+                if (pos) {
+                    output += polybius[coords[0]][coords[1]];
+                } else {
+                    output += polybius[coords[0]][coords[1]].toLocaleLowerCase();
+                }
+                count++;
+            } else {
+                output += pos;
+            }
+        });
+        return output;
+    },
+
+    /**
+     * Bifid Cipher Decode operation
+     *
+     * @author Matt C [matt@artemisbot.uk]
+     * @param {string} input
+     * @param {Object[]} args
+     * @returns {string}
+     */
+    runBifidDec: function (input, args) {
+        const keyword = args[0].toUpperCase().replace("J", "I"),
+            alpha = "ABCDEFGHIKLMNOPQRSTUVWXYZ";
+        let output = "",
+            structure = [],
+            count = 0,
+            trans = "";
+        if (keyword.split("").unique().length > 25) return "The alphabet keyword must be less than 25 characters.";
+        if (!/^[a-zA-Z]+$/.test(keyword) && keyword.split("").unique().length > 0) return "The key must consist only of letters";
+        const polybius = Cipher.genPolybiusSquare(keyword);
+        input.replace("J", "I").split("").forEach((letter) => {
+            let alpInd = alpha.split("").indexOf(letter.toLocaleUpperCase()) >= 0,
+                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") {
+                let coords = [trans[count], trans[count+trans.length/2]];
+                if (pos) {
+                    output += polybius[coords[0]][coords[1]];
+                } else {
+                    output += polybius[coords[0]][coords[1]].toLocaleLowerCase();
+                }
+                count++;
+            } else {
+                output += pos;
+            }
+        });
+        return output;
+    },
 
     /**
      * @constant

+ 1 - 0
test/index.js

@@ -14,6 +14,7 @@ import TestRegister from "./TestRegister.js";
 import "./tests/operations/Base58.js";
 import "./tests/operations/ByteRepr.js";
 import "./tests/operations/CharEnc.js";
+import "./tests/operations/Cipher.js";
 import "./tests/operations/Code.js";
 import "./tests/operations/Compress.js";
 import "./tests/operations/DateTime.js";

+ 78 - 0
test/tests/operations/Cipher.js

@@ -0,0 +1,78 @@
+/**
+ * Cipher tests.
+ *
+ * @author Matt C [matt@artemisbot.uk]
+ *
+ * @copyright Crown Copyright 2017
+ * @license Apache-2.0
+ */
+import TestRegister from "../../TestRegister.js";
+
+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"]
+            }
+        ],
+    },
+]);