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;
+ };
+ })(),
+
+};