From 560712cee373921c4fb7c45938cc4ae5d360df3d Mon Sep 17 00:00:00 2001 From: Matt C Date: Sat, 3 Dec 2016 20:54:28 +0000 Subject: [PATCH] Feature: Add Vigenere Cipher Encode & Decode - Added Vigenere Encode & Decode - Added metadata for /config/ relating to this additon --- src/js/config/Categories.js | 2 + src/js/config/OperationConfig.js | 30 ++++++++++ src/js/operations/Cipher.js | 97 +++++++++++++++++++++++++++++++- 3 files changed, 128 insertions(+), 1 deletion(-) diff --git a/src/js/config/Categories.js b/src/js/config/Categories.js index 02c2b1f5..640e5fe9 100755 --- a/src/js/config/Categories.js +++ b/src/js/config/Categories.js @@ -81,6 +81,8 @@ var Categories = [ "XOR Brute Force", "Derive PBKDF2 key", "Derive EVP key", + "Vigenere Encode", + "Vigenere Decode" ] }, { diff --git a/src/js/config/OperationConfig.js b/src/js/config/OperationConfig.js index bebaaad4..7c2136d7 100755 --- a/src/js/config/OperationConfig.js +++ b/src/js/config/OperationConfig.js @@ -1325,6 +1325,36 @@ var OperationConfig = { }, ] }, + "Vigenere Encode": { + description: "Encodes string with the Vigenere cipher.", + run: Cipher.run_vigenc, + highlight: true, + highlight_reverse: true, + input_type: "string", + output_type: "string", + args: [ + { + name: "Keyword", + type: "string", + value: Cipher.VIG_ENC_KEY + } + ] + }, + "Vigenere Decode": { + description: "Decodes string with the Vigenere cipher.", + run: Cipher.run_vigdec, + highlight: true, + highlight_reverse: true, + input_type: "string", + output_type: "string", + args: [ + { + name: "Keyword", + type: "string", + value: Cipher.VIG_DEC_KEY + } + ] + }, "Rotate right": { description: "Rotates each byte to the right by the number of bits specified. Currently only supports 8-bit values.", run: Rotate.run_rotr, diff --git a/src/js/operations/Cipher.js b/src/js/operations/Cipher.js index 94193546..2c28dd12 100755 --- a/src/js/operations/Cipher.js +++ b/src/js/operations/Cipher.js @@ -3,7 +3,7 @@ /** * Cipher operations. * - * @author n1474335 [n1474335@gmail.com] + * @author n1474335 [n1474335@gmail.com] & Matt C [matt@artemisbot.pw] * @copyright Crown Copyright 2016 * @license Apache-2.0 * @@ -385,6 +385,101 @@ var Cipher = { return encrypted.ciphertext.toString(Utils.format[args[2]]); }, + + /** + * @constant + * @default + */ + VIG_ENC_KEY: "cipher", + + /** + * Vigenere cipher encode. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run_vigenc: function (input, args) { + var alphabet = "abcdefghijklmnopqrstuvwxyz", + keyword = args[0].toLowerCase(), + output = "", + fail = 0, + keyIndex, + msgIndex, + chr; + if (keyword) { + if (/^[a-zA-Z]+$/.test(keyword)) { + for (var i = 0; i < input.length; i++) { + if (alphabet.indexOf(input[i]) >= 0) { + chr = keyword[(i - fail) % keyword.length]; //Gets the corresponding character of keyword for current letter, accounting for chars not in alphabet + keyIndex = alphabet.indexOf(chr); //Gets location in vigenere square of keyword char + msgIndex = alphabet.indexOf(input[i]); //Gets location in vigenere square of message char + output += alphabet[(keyIndex + msgIndex) % 26]; //Gets encoded letter by finding sum of indexes modulo 26 and finding the letter corresponding to that + } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) { + chr = keyword[(i - fail) % keyword.length].toLowerCase(); + keyIndex = alphabet.indexOf(chr); + msgIndex = alphabet.indexOf(input[i].toLowerCase()); + output += alphabet[(keyIndex + msgIndex) % 26].toUpperCase(); + } else { + output += input[i]; + fail++ + } + } + } else { + throw "Keyword can only consist of letters."; + } + } else { + throw "A keyword is required."; + } + return output; + }, + /** + * @constant + * @default + */ + VIG_DEC_KEY: "cipher", + + /** + * Vigenere cipher decode. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + run_vigdec: function (input, args) { + var alphabet = "abcdefghijklmnopqrstuvwxyz", + keyword = args[0].toLowerCase(), + output = "", + fail = 0, + keyIndex, + msgIndex, + chr; + if (keyword) { + if (/^[a-zA-Z]+$/.test(keyword)) { + for (var i = 0; i < input.length; i++) { + if (alphabet.indexOf(input[i]) >= 0) { + chr = keyword[(i - fail) % keyword.length]; + keyIndex = alphabet.indexOf(chr); + msgIndex = alphabet.indexOf(input[i]); + output += alphabet[(msgIndex - keyIndex + alphabet.length ) % 26]; //subtract indexes from each other, add 26 just in case the value is negative, modulo to remove if neccessary + } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) { + chr = keyword[(i - fail) % keyword.length].toLowerCase(); + keyIndex = alphabet.indexOf(chr); + msgIndex = alphabet.indexOf(input[i].toLowerCase()); + output += alphabet[(msgIndex + alphabet.length - keyIndex) % 26].toUpperCase(); + } else { + output += input[i]; + fail++ + } + } + } else { + throw "Keyword can only consist of letters."; + } + } else { + throw "A keyword is required."; + } + return output; + } };