diff --git a/Ciphers/CaesarCipher.js b/Ciphers/CaesarCipher.js index 8a942564e9..3e4e4f44a6 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 cipherMap.get(char) - }) -} +// Example usage: +console.log(caesarCipher('Hello World!', 3)); // Khoor Zruog! -export default caesarCipher +export default caesarCipher;