merge: Improved CaesarsCipher Algorithm (#963)

* chore: added helper variable

* feat: added new rotation option

* Revert "chore: added helper variable"

This reverts commit 489544da0a3d479910fbea020d3be3d0d10681bf.
This commit is contained in:
Fahim Faisaal
2022-03-29 12:35:58 +06:00
committed by GitHub
parent 7d57f7f1a7
commit cdfa264b33
2 changed files with 43 additions and 30 deletions

View File

@ -1,35 +1,32 @@
/**
* Caesar's Cipher - also known as the ROT13 Cipher is when
* a letter is replaced by the one that is 13 spaces away
* from it in the alphabet. If the letter is in the first half
* of the alphabet we add 13, if it's in the latter half we
* subtract 13 from the character code value.
* @function caesarsCipher
* @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.
* @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)
* @return {string} - decrypted string
*/
/**
* Decrypt a ROT13 cipher
* @param {String} str - string to be decrypted
* @return {String} decrypted string
*/
function rot13 (str) {
const response = []
const strLength = str.length
for (let i = 0; i < strLength; i++) {
const char = str.charCodeAt(i)
if (char < 65 || (char > 90 && char < 97) || char > 122) {
response.push(str.charAt(i))
} else if ((char > 77 && char <= 90) || (char > 109 && char <= 122)) {
response.push(String.fromCharCode(str.charCodeAt(i) - 13))
} else {
response.push(String.fromCharCode(str.charCodeAt(i) + 13))
const caesarsCipher = (str, rotation) => {
if (typeof str !== 'string' || !Number.isInteger(rotation) || rotation < 0) {
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 cipherMap = alphabets.reduce(
(map, char, index) => map.set(char, alphabets[(rotation + index) % 26]),
new Map()
)
return str.replace(/[a-z]/gi, (char) => {
if (/[A-Z]/.test(char)) {
return cipherMap.get(char.toLowerCase()).toUpperCase()
}
return response.join('')
return cipherMap.get(char)
})
}
export { rot13 }
// > rot13('Uryyb Jbeyq')
// 'Hello World'
export default caesarsCipher

View File

@ -0,0 +1,16 @@
import caesarsCipher from '../CaesarsCipher'
describe('Testing the caesarsCipher function', () => {
it('Test - 1, Testing for invalid types', () => {
expect(() => caesarsCipher(false, 3)).toThrow()
expect(() => caesarsCipher('false', -1)).toThrow()
expect(() => caesarsCipher('true', null)).toThrow()
})
it('Test - 2, Testing for valid string and rotation', () => {
expect(caesarsCipher('middle-Outz', 2)).toBe('okffng-Qwvb')
expect(caesarsCipher('abcdefghijklmnopqrstuvwxyz', 3)).toBe('defghijklmnopqrstuvwxyzabc')
expect(caesarsCipher('Always-Look-on-the-Bright-Side-of-Life', 5)).toBe('Fqbfdx-Qttp-ts-ymj-Gwnlmy-Xnij-tk-Qnkj')
expect(caesarsCipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG', 23)).toBe('QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD')
})
})