From 9c3ddca2694a75c6cae734372feff833e0085328 Mon Sep 17 00:00:00 2001 From: Samuele Facenda Date: Sun, 13 Nov 2022 14:37:19 +0100 Subject: [PATCH] Added ignoreCase feature in Substitute operation. --- src/core/operations/Substitute.mjs | 58 +++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 8 deletions(-) diff --git a/src/core/operations/Substitute.mjs b/src/core/operations/Substitute.mjs index 1afe1f42..1dac1c53 100644 --- a/src/core/operations/Substitute.mjs +++ b/src/core/operations/Substitute.mjs @@ -34,10 +34,49 @@ class Substitute extends Operation { "name": "Ciphertext", "type": "binaryString", "value": "XYZABCDEFGHIJKLMNOPQRSTUVW" + }, + { + "name": "Ignore case", + "type": "boolean", + "value": false } ]; } + /** + * Convert a single character using the dictionary, if ignoreCase is true then + * check in the dictionary for both upper and lower case versions of the character. + * In output the input character case is preserved. + * @param {string} char + * @param {Object} dict + * @param {boolean} ignoreCase + * @returns {string} + */ + cipherSingleChar(char, dict, ignoreCase) { + if (!ignoreCase) + return dict[char] || char; + + const isUpperCase = char === char.toUpperCase(); + + // convert using the dictionary keeping the case of the input character + + if (dict[char] !== undefined) + // if the character is in the dictionary return the value with the input case + return isUpperCase ? dict[char].toUpperCase() : dict[char].toLowerCase(); + + // check for the other case, if it is in the dictionary return the value with the right case + if (isUpperCase) { + if (dict[char.toLowerCase()] !== undefined) + return dict[char.toLowerCase()].toUpperCase(); + } else { + if(dict[char.toUpperCase()] !== undefined) + return dict[char.toUpperCase()].toLowerCase(); + } + + return char; + } + + /** * @param {string} input * @param {Object[]} args @@ -46,17 +85,20 @@ class Substitute extends Operation { run(input, args) { const plaintext = Utils.expandAlphRange([...args[0]]), ciphertext = Utils.expandAlphRange([...args[1]]); - let output = "", - index = -1; + let output = ""; + const ignoreCase = args[2]; - if (plaintext.length !== ciphertext.length) { + if (plaintext.length !== ciphertext.length) output = "Warning: Plaintext and Ciphertext lengths differ\n\n"; - } - for (const character of input) { - index = plaintext.indexOf(character); - output += index > -1 && index < ciphertext.length ? ciphertext[index] : character; - } + // create dictionary for conversion + const dict = {}; + for (let i = 0; i < Math.min(ciphertext.length, plaintext.length); i++) + dict[plaintext[i]] = ciphertext[i]; + + // map every letter with the conversion function + for (const character of input) + output += this.cipherSingleChar(character, dict, ignoreCase); return output; }