Skip to content

Commit cdfa264

Browse files
authored
merge: Improved CaesarsCipher Algorithm (TheAlgorithms#963)
* chore: added helper variable * feat: added new rotation option * Revert "chore: added helper variable" This reverts commit 489544d.
1 parent 7d57f7f commit cdfa264

File tree

2 files changed

+40
-27
lines changed

2 files changed

+40
-27
lines changed

Ciphers/CaesarsCipher.js

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,32 @@
11
/**
2-
* Caesar's Cipher - also known as the ROT13 Cipher is when
3-
* a letter is replaced by the one that is 13 spaces away
4-
* from it in the alphabet. If the letter is in the first half
5-
* of the alphabet we add 13, if it's in the latter half we
6-
* subtract 13 from the character code value.
2+
* @function caesarsCipher
3+
* @description - In cryptography, a Caesar cipher, also known as Caesar's cipher, the shift cipher, Caesar's code or Caesar shift, is one of the simplest and most widely known encryption techniques. It is a type of substitution cipher in which each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. For example, with a left shift of 3, D would be replaced by A, E would become B, and so on. The method is named after Julius Caesar, who used it in his private correspondence.
4+
* @see - [wiki](https://en.wikipedia.org/wiki/Caesar_cipher)
5+
* @param {string} str - string to be encrypted
6+
* @param {number} rotation - the number of rotation, expect real number ( > 0)
7+
* @return {string} - decrypted string
78
*/
9+
const caesarsCipher = (str, rotation) => {
10+
if (typeof str !== 'string' || !Number.isInteger(rotation) || rotation < 0) {
11+
throw new TypeError('Arguments are invalid')
12+
}
813

9-
/**
10-
* Decrypt a ROT13 cipher
11-
* @param {String} str - string to be decrypted
12-
* @return {String} decrypted string
13-
*/
14-
function rot13 (str) {
15-
const response = []
16-
const strLength = str.length
14+
const alphabets = new Array(26)
15+
.fill()
16+
.map((_, index) => String.fromCharCode(97 + index)) // generate all lower alphabets array a-z
1717

18-
for (let i = 0; i < strLength; i++) {
19-
const char = str.charCodeAt(i)
18+
const cipherMap = alphabets.reduce(
19+
(map, char, index) => map.set(char, alphabets[(rotation + index) % 26]),
20+
new Map()
21+
)
2022

21-
if (char < 65 || (char > 90 && char < 97) || char > 122) {
22-
response.push(str.charAt(i))
23-
} else if ((char > 77 && char <= 90) || (char > 109 && char <= 122)) {
24-
response.push(String.fromCharCode(str.charCodeAt(i) - 13))
25-
} else {
26-
response.push(String.fromCharCode(str.charCodeAt(i) + 13))
23+
return str.replace(/[a-z]/gi, (char) => {
24+
if (/[A-Z]/.test(char)) {
25+
return cipherMap.get(char.toLowerCase()).toUpperCase()
2726
}
28-
}
29-
return response.join('')
30-
}
3127

32-
export { rot13 }
28+
return cipherMap.get(char)
29+
})
30+
}
3331

34-
// > rot13('Uryyb Jbeyq')
35-
// 'Hello World'
32+
export default caesarsCipher

Ciphers/test/CaesarsCipher.test.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import caesarsCipher from '../CaesarsCipher'
2+
3+
describe('Testing the caesarsCipher function', () => {
4+
it('Test - 1, Testing for invalid types', () => {
5+
expect(() => caesarsCipher(false, 3)).toThrow()
6+
expect(() => caesarsCipher('false', -1)).toThrow()
7+
expect(() => caesarsCipher('true', null)).toThrow()
8+
})
9+
10+
it('Test - 2, Testing for valid string and rotation', () => {
11+
expect(caesarsCipher('middle-Outz', 2)).toBe('okffng-Qwvb')
12+
expect(caesarsCipher('abcdefghijklmnopqrstuvwxyz', 3)).toBe('defghijklmnopqrstuvwxyzabc')
13+
expect(caesarsCipher('Always-Look-on-the-Bright-Side-of-Life', 5)).toBe('Fqbfdx-Qttp-ts-ymj-Gwnlmy-Xnij-tk-Qnkj')
14+
expect(caesarsCipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG', 23)).toBe('QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD')
15+
})
16+
})

0 commit comments

Comments
 (0)