diff --git a/src/js/config/Categories.js b/src/js/config/Categories.js index 8a645e3..aeb783e 100755 --- a/src/js/config/Categories.js +++ b/src/js/config/Categories.js @@ -82,6 +82,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 0dd9e22..96c46fb 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 9419354..1947829 100755 --- a/src/js/operations/Cipher.js +++ b/src/js/operations/Cipher.js @@ -385,6 +385,103 @@ var Cipher = { return encrypted.ciphertext.toString(Utils.format[args[2]]); }, + + /** + * @constant + * @default + */ + VIG_ENC_KEY: "cipher", + + /** + * Vigenere cipher encode. + * + * @author Matt C [matt@artemisbot.pw] + * @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. + * + * @author Matt C [matt@artemisbot.pw] + * @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; + } };