diff --git a/src/js/config/Categories.js b/src/js/config/Categories.js index db43721c..dfe056b8 100755 --- a/src/js/config/Categories.js +++ b/src/js/config/Categories.js @@ -85,6 +85,8 @@ var Categories = [ "Substitute", "Derive PBKDF2 key", "Derive EVP key", + "To Morse Code", + "From Morse Code", ] }, { diff --git a/src/js/config/OperationConfig.js b/src/js/config/OperationConfig.js index cdfa9cdc..0fd2367e 100755 --- a/src/js/config/OperationConfig.js +++ b/src/js/config/OperationConfig.js @@ -2952,5 +2952,46 @@ var OperationConfig = { value: Cipher.SUBS_CIPHERTEXT } ] + }, + "To Morse Code": { + description: "Translates alphanumeric characters into International Morse Code.

Ignores non-Morse characters.

e.g. SOS becomes ... --- ...", + run: MorseCode.translateTo, + inputType: "string", + outputType: "string", + args: [ + { + name: "Format options", + type: "option", + value: MorseCode.FORMAT_OPTIONS + }, + { + name: "Letter delimiter", + type: "option", + value: MorseCode.LETTER_DELIM_OPTIONS + }, + { + name: "Word delimiter", + type: "option", + value: MorseCode.WORD_DELIM_OPTIONS + } + ] + }, + "From Morse Code": { + description: "Translates Morse Code into (upper case) alphanumeric characters.", + run: MorseCode.translateFrom, + inputType: "string", + outputType: "string", + args: [ + { + name: "Letter delimiter", + type: "option", + value: MorseCode.LETTER_DELIM_OPTIONS + }, + { + name: "Word delimiter", + type: "option", + value: MorseCode.WORD_DELIM_OPTIONS + } + ] } }; diff --git a/src/js/operations/MorseCode.js b/src/js/operations/MorseCode.js new file mode 100644 index 00000000..8001a152 --- /dev/null +++ b/src/js/operations/MorseCode.js @@ -0,0 +1,169 @@ +/** + * Morse Code translation operations. + * + * @author tlwr [toby@toby.codes] + * @copyright Crown Copyright 2017 + * @license Apache-2.0 + * + * @namespace + */ +var MorseCode = { + + /** + * @constant + * @default + */ + FORMAT_OPTIONS: ["-/.", "_/.", "Dash/Dot", "DASH/DOT", "dash/dot"], + + /** + * @constant + * @default + */ + LETTER_DELIM_OPTIONS: ["space", "line feed", "crlf"], + + /** + * @constant + * @default + */ + WORD_DELIM_OPTIONS: ["line feed", "crlf", "space"], + + /** + * @constant + * @default + */ + OPTION_TABLE: { + "space": " ", + "line feed": "\n", + "crlf": "\r\n" + }, + + /** + * @constant + * @default + */ + MORSE_TABLE: { + "A": "", + "B": "", + "C": "", + "D": "", + "E": "", + "F": "", + "G": "", + "H": "", + "I": "", + "J": "", + "K": "", + "L": "", + "M": "", + "N": "", + "O": "", + "P": "", + "Q": "", + "R": "", + "S": "", + "T": "", + "U": "", + "V": "", + "W": "", + "X": "", + "Y": "", + "Z": "", + "1": "", + "2": "", + "3": "", + "4": "", + "5": "", + "6": "", + "7": "", + "8": "", + "9": "", + "0": "", + }, + + + /** + * To Morse Code operation. + * + * @param {number} input + * @param {Object[]} args + * @returns {string} + */ + translateTo: function(input, args) { + var format = args[0].split("/"); + var dash = format[0]; + var dot = format[1]; + + var letter_delim = MorseCode.OPTION_TABLE[args[1]]; + var word_delim = MorseCode.OPTION_TABLE[args[2]]; + + var words = input.split(/ +/); + words = Array.prototype.map.call(words, function(word) { + var letters = Array.prototype.map.call(word, function(character) { + var letter = character.toUpperCase(); + if(typeof MorseCode.MORSE_TABLE[letter] == "undefined") { + return ""; + } + + return MorseCode.MORSE_TABLE[letter]; + }); + + return letters.join(""); + }); + + var morse = words.join(""); + morse = morse.replace(//g, dash); + morse = morse.replace(//g, dot); + morse = morse.replace(//g, letter_delim); + morse = morse.replace(//g, word_delim); + + return morse; + }, + + + /** + * From Morse Code operation. + * + * @param {string} input + * @param {Object[]} args + * @returns {string} + */ + translateFrom: (function() { + var reversedTable = null; + var reverseTable = function() { + reversedTable = {}; + + for(var letter in MorseCode.MORSE_TABLE) { + var signal = MorseCode.MORSE_TABLE[letter]; + reversedTable[signal] = letter; + } + }; + + return function(input, args) { + if(reversedTable === null) { + reverseTable(); + } + + var letter_delim = MorseCode.OPTION_TABLE[args[0]]; + var word_delim = MorseCode.OPTION_TABLE[args[1]]; + + input = input.replace(/-|_|dash/ig, "") + input = input.replace(/\.|dot/ig, "") + + var words = input.split(word_delim); + words = Array.prototype.map.call(words, function(word) { + var signals = word.split(letter_delim); + + var letters = signals.map(function(signal) { + return reversedTable[signal]; + }); + + var word = letters.join(""); + return word; + }); + words = words.join(" "); + + return words; + }; + })(), + +};