From 2bce9498f9b1d03986b3b91f69d3c83c8095cb0f Mon Sep 17 00:00:00 2001 From: Aleksandar Todorov <101955939+AlexTodorov11@users.noreply.github.com> Date: Tue, 8 Oct 2024 23:32:17 +0300 Subject: [PATCH 1/2] Enhancements to Caesar Cipher Implementation - CaesarCipher.js Improves the existing Caesar Cipher implementation to make it more robust, future-proof, and flexible. Key improvements include handling edge cases, optimizing performance, and adding support for custom alphabets. These changes enhance both the functionality and maintainability of the code. --- Ciphers/CaesarCipher.js | 43 +++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/Ciphers/CaesarCipher.js b/Ciphers/CaesarCipher.js index 8a942564e9..000a3d676f 100644 --- a/Ciphers/CaesarCipher.js +++ b/Ciphers/CaesarCipher.js @@ -4,29 +4,42 @@ * @see - [wiki](https://en.wikipedia.org/wiki/Caesar_cipher) * @param {string} str - string to be encrypted * @param {number} rotation - the number of rotation, expect real number ( > 0) + * @param {string} [alphabet='abcdefghijklmnopqrstuvwxyz'] - Optional parameter to specify a custom alphabet * @return {string} - decrypted string */ -const caesarCipher = (str, rotation) => { +const caesarCipher = (str, rotation, alphabet = 'abcdefghijklmnopqrstuvwxyz') => { if (typeof str !== 'string' || !Number.isInteger(rotation) || rotation < 0) { - throw new TypeError('Arguments are invalid') + throw new TypeError('Arguments are invalid'); } - const alphabets = new Array(26) - .fill() - .map((_, index) => String.fromCharCode(97 + index)) // generate all lower alphabets array a-z + const alphabets = Array.from(alphabet); // Allow custom alphabet + const alphabetLength = alphabets.length; - const cipherMap = alphabets.reduce( - (map, char, index) => map.set(char, alphabets[(rotation + index) % 26]), - new Map() - ) + // Optimize rotation to handle rotations greater than alphabet length + const effectiveRotation = rotation % alphabetLength; + + // Create cipher map to avoid recalculating for each character + const cipherMap = alphabets.reduce((map, char, index) => { + map.set(char, alphabets[(effectiveRotation + index) % alphabetLength]); + return map; + }, new Map()); return str.replace(/[a-z]/gi, (char) => { - if (/[A-Z]/.test(char)) { - return cipherMap.get(char.toLowerCase()).toUpperCase() + const isUpperCase = /[A-Z]/.test(char); + const lowerChar = char.toLowerCase(); + + // Check if the character is in the map (i.e., an alphabetic character) + if (cipherMap.has(lowerChar)) { + const cipheredChar = cipherMap.get(lowerChar); + return isUpperCase ? cipheredChar.toUpperCase() : cipheredChar; } - return cipherMap.get(char) - }) -} + // Return non-alphabetic characters unchanged + return char; + }); +}; + +// Example usage: +console.log(caesarCipher('Hello World!', 3)); // Khoor Zruog! -export default caesarCipher +export default caesarCipher; From ab9ba901c020caf7a3bea92ab6de5aaba05b02e6 Mon Sep 17 00:00:00 2001 From: Aleksandar Todorov <101955939+AlexTodorov11@users.noreply.github.com> Date: Wed, 9 Oct 2024 00:02:41 +0300 Subject: [PATCH 2/2] Update CaesarCipher.js --- Ciphers/CaesarCipher.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Ciphers/CaesarCipher.js b/Ciphers/CaesarCipher.js index 000a3d676f..3e4e4f44a6 100644 --- a/Ciphers/CaesarCipher.js +++ b/Ciphers/CaesarCipher.js @@ -32,11 +32,11 @@ const caesarCipher = (str, rotation, alphabet = 'abcdefghijklmnopqrstuvwxyz') => if (cipherMap.has(lowerChar)) { const cipheredChar = cipherMap.get(lowerChar); return isUpperCase ? cipheredChar.toUpperCase() : cipheredChar; - } + } + + return cipherMap.get(char); +}); - // Return non-alphabetic characters unchanged - return char; - }); }; // Example usage: