From 230ba5ff67901d9bd56cbf4c8ef3a762b003606a Mon Sep 17 00:00:00 2001 From: toby Date: Fri, 3 Feb 2017 16:43:30 -0500 Subject: [PATCH 1/3] Add initial functionality Added "To Morse Code" and "From More Code" functions under the category "Encryption / Encoding". "To Morse Code" accepts 3 arguments: 1. Format options: e.g. ./- or Dot/Dash 2. Letter delimiter e.g. or 3. Word delimiter e.g. "From Morse Code" accepts 2 arguments: 1. Letter delimiter 2. Word delimiter --- src/js/config/Categories.js | 2 + src/js/config/OperationConfig.js | 41 ++++++++ src/js/operations/MorseCode.js | 169 +++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+) create mode 100644 src/js/operations/MorseCode.js diff --git a/src/js/config/Categories.js b/src/js/config/Categories.js index db43721..dfe056b 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 cdfa9cd..0fd2367 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 0000000..8001a15 --- /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; + }; + })(), + +}; From 9bf0d66b8854eaa21540f6379a37511f3ad3cb17 Mon Sep 17 00:00:00 2001 From: toby Date: Fri, 3 Feb 2017 17:54:50 -0500 Subject: [PATCH 2/3] Fix casing for Morse code operations + description --- src/js/config/Categories.js | 4 ++-- src/js/config/OperationConfig.js | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/js/config/Categories.js b/src/js/config/Categories.js index dfe056b..f76431a 100755 --- a/src/js/config/Categories.js +++ b/src/js/config/Categories.js @@ -85,8 +85,8 @@ var Categories = [ "Substitute", "Derive PBKDF2 key", "Derive EVP key", - "To Morse Code", - "From Morse Code", + "To Morse code", + "From Morse code", ] }, { diff --git a/src/js/config/OperationConfig.js b/src/js/config/OperationConfig.js index 0fd2367..a1391a7 100755 --- a/src/js/config/OperationConfig.js +++ b/src/js/config/OperationConfig.js @@ -2953,8 +2953,8 @@ var OperationConfig = { } ] }, - "To Morse Code": { - description: "Translates alphanumeric characters into International Morse Code.

Ignores non-Morse characters.

e.g. SOS becomes ... --- ...", + "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", @@ -2976,8 +2976,8 @@ var OperationConfig = { } ] }, - "From Morse Code": { - description: "Translates Morse Code into (upper case) alphanumeric characters.", + "From Morse code": { + description: "Translates Morse code into (upper case) alphanumeric characters.", run: MorseCode.translateFrom, inputType: "string", outputType: "string", From b9f1cf968fb60b4f71c782ada3022622cd9c26e7 Mon Sep 17 00:00:00 2001 From: toby Date: Fri, 3 Feb 2017 18:34:46 -0500 Subject: [PATCH 3/3] Make translateTo faster and aware of line breaks Speed improvement is due to using a function regex instead of multiple find/replace calls. --- src/js/operations/MorseCode.js | 44 +++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/js/operations/MorseCode.js b/src/js/operations/MorseCode.js index 8001a15..a9cab2d 100644 --- a/src/js/operations/MorseCode.js +++ b/src/js/operations/MorseCode.js @@ -96,27 +96,39 @@ var MorseCode = { 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 ""; - } + input = input.split(/\r?\n/); + input = Array.prototype.map.call(input, function(line) { + var words = line.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 MorseCode.MORSE_TABLE[letter]; + }); + + return letters.join(""); }); - - return letters.join(""); + line = words.join(""); + return line; }); + input = input.join("\n"); - 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); + input = input.replace( + /|||/g, + function(match) { + switch(match) { + case "": return dash; + case "": return dot; + case "": return letter_delim; + case "": return word_delim; + } + } + ); - return morse; + return input; },