Skip to content

Commit 2bce949

Browse files
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.
1 parent 18da83a commit 2bce949

File tree

1 file changed

+28
-15
lines changed

1 file changed

+28
-15
lines changed

Ciphers/CaesarCipher.js

+28-15
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,42 @@
44
* @see - [wiki](https://en.wikipedia.org/wiki/Caesar_cipher)
55
* @param {string} str - string to be encrypted
66
* @param {number} rotation - the number of rotation, expect real number ( > 0)
7+
* @param {string} [alphabet='abcdefghijklmnopqrstuvwxyz'] - Optional parameter to specify a custom alphabet
78
* @return {string} - decrypted string
89
*/
9-
const caesarCipher = (str, rotation) => {
10+
const caesarCipher = (str, rotation, alphabet = 'abcdefghijklmnopqrstuvwxyz') => {
1011
if (typeof str !== 'string' || !Number.isInteger(rotation) || rotation < 0) {
11-
throw new TypeError('Arguments are invalid')
12+
throw new TypeError('Arguments are invalid');
1213
}
1314

14-
const alphabets = new Array(26)
15-
.fill()
16-
.map((_, index) => String.fromCharCode(97 + index)) // generate all lower alphabets array a-z
15+
const alphabets = Array.from(alphabet); // Allow custom alphabet
16+
const alphabetLength = alphabets.length;
1717

18-
const cipherMap = alphabets.reduce(
19-
(map, char, index) => map.set(char, alphabets[(rotation + index) % 26]),
20-
new Map()
21-
)
18+
// Optimize rotation to handle rotations greater than alphabet length
19+
const effectiveRotation = rotation % alphabetLength;
20+
21+
// Create cipher map to avoid recalculating for each character
22+
const cipherMap = alphabets.reduce((map, char, index) => {
23+
map.set(char, alphabets[(effectiveRotation + index) % alphabetLength]);
24+
return map;
25+
}, new Map());
2226

2327
return str.replace(/[a-z]/gi, (char) => {
24-
if (/[A-Z]/.test(char)) {
25-
return cipherMap.get(char.toLowerCase()).toUpperCase()
28+
const isUpperCase = /[A-Z]/.test(char);
29+
const lowerChar = char.toLowerCase();
30+
31+
// Check if the character is in the map (i.e., an alphabetic character)
32+
if (cipherMap.has(lowerChar)) {
33+
const cipheredChar = cipherMap.get(lowerChar);
34+
return isUpperCase ? cipheredChar.toUpperCase() : cipheredChar;
2635
}
2736

28-
return cipherMap.get(char)
29-
})
30-
}
37+
// Return non-alphabetic characters unchanged
38+
return char;
39+
});
40+
};
41+
42+
// Example usage:
43+
console.log(caesarCipher('Hello World!', 3)); // Khoor Zruog!
3144

32-
export default caesarCipher
45+
export default caesarCipher;

0 commit comments

Comments
 (0)