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: