Skip to content

Commit 7d40bb4

Browse files
authored
merge: Add Affine Cipher (TheAlgorithms#1067)
* Add Affine Cipher * Replace IndexOf function to improve performance * remove leading spacing and fixed typo * Remove leading spacing in first row.
1 parent bbbf343 commit 7d40bb4

File tree

2 files changed

+122
-0
lines changed

2 files changed

+122
-0
lines changed

‎Ciphers/AffineCipher.js‎

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* @description - The affine cipher is a type of monoalphabetic substitution cipher, where each letter in an alphabet is mapped to its numeric equivalent, encrypted using a simple mathematical function, and converted back to a letter
3+
* @see - [wiki](https://en.wikipedia.org/wiki/Affine_cipher)
4+
*/
5+
6+
// Default key for Affine Cipher
7+
constkey='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
8+
9+
/**
10+
* Fix result for negative value in modulas equation
11+
* @param{Number} n - Constant number
12+
* @param{Number} m - Modulos value
13+
* @return{Number} Return n mod m
14+
*/
15+
functionmod(n,m){
16+
return((n%m)+m)%m
17+
}
18+
19+
/**
20+
* Modular multiplicative inverse
21+
* @param{Number} a - A coefficient
22+
* @param{Number} m - Modulos value
23+
* @return{Number} Return modular multiplicative inverse of coefficient a and modulos m
24+
*/
25+
functioninverseMod(a,m){
26+
for(letx=1;x<m;x++){
27+
if(mod(a*x,m)===1)returnx
28+
}
29+
}
30+
31+
/**
32+
* Argument validation
33+
* @param{String} str - String to be checked
34+
* @param{Number} a - A coefficient to be checked
35+
* @param{Number} b - B coefficient to be checked
36+
* @return{Boolean} Result of the checking
37+
*/
38+
functionisCorrectFormat(str,a,b){
39+
if(typeofa!=='number'||typeofb!=='number'){
40+
thrownewTypeError('Coefficient a, b should be number')
41+
}
42+
43+
if(typeofstr!=='string'){
44+
thrownewTypeError('Argument str should be String')
45+
}
46+
47+
returntrue
48+
}
49+
/**
50+
* Find character index based on ASCII order
51+
* @param{String} char - Character index to be found
52+
* @return{Boolean} Character index
53+
*/
54+
functionfindCharIndex(char){
55+
returnchar.toUpperCase().charCodeAt(0)-('A').charCodeAt(0)
56+
}
57+
58+
/**
59+
* Encrypt a Affine Cipher
60+
* @param{String} str - String to be encrypted
61+
* @param{Number} a - A coefficient
62+
* @param{Number} b - B coefficient
63+
* @return{String} result - Encrypted string
64+
*/
65+
functionencrypt(str,a,b){
66+
letresult=''
67+
if(isCorrectFormat(str,a,b)){
68+
for(letx=0;x<str.length;x++){
69+
constcharIndex=findCharIndex(str[x])
70+
if(charIndex<0)result+='-1'+' '
71+
elseresult+=mod(a*charIndex+b,26)+' '
72+
}
73+
}
74+
returnresult.trim()
75+
}
76+
/**
77+
* Decrypt a Affine Cipher
78+
* @param{String} str - String to be decrypted
79+
* @param{Number} a - A coefficient
80+
* @param{Number} b - B coefficient
81+
* @return{String} result - Decrypted string
82+
*/
83+
functiondecrypt(str,a,b){
84+
letresult=''
85+
if(isCorrectFormat(str,a,b)){
86+
str=str.split(' ')
87+
for(letx=0;x<str.length;x++){
88+
if(str[x]==='-1')result+=' '
89+
elseresult+=key[mod(inverseMod(a,26)*(parseInt(str[x])-b),26)]
90+
}
91+
}
92+
returnresult
93+
}
94+
95+
export{encrypt,decrypt}

‎Ciphers/test/AffineCipher.test.js‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import{encrypt,decrypt}from'../AffineCipher'
2+
3+
describe('Test Affine Cipher',()=>{
4+
it('Test - 1, Pass invalid input to encrypt function',()=>{
5+
expect(()=>encrypt(null,null,null)).toThrow()
6+
expect(()=>encrypt('null',null,null)).toThrow()
7+
expect(()=>encrypt('null',1,null)).toThrow()
8+
expect(()=>encrypt('null',null,1)).toThrow()
9+
})
10+
11+
it('Test - 2, Pass invalid input to decrypt function',()=>{
12+
expect(()=>decrypt(null,null,null)).toThrow()
13+
expect(()=>decrypt('null',null,null)).toThrow()
14+
expect(()=>decrypt('null',1,null)).toThrow()
15+
expect(()=>decrypt('null',null,1)).toThrow()
16+
})
17+
18+
it('Test - 3 Pass string value to encrypt and ecrypt function',()=>{
19+
consta=5
20+
constb=8
21+
expect(decrypt(encrypt('HELLO WORLD',a,b),a,b)).toBe('HELLO WORLD')
22+
expect(decrypt(encrypt('ABC DEF',a,b),a,b)).toBe('ABC DEF')
23+
expect(decrypt(encrypt('Brown fox jump over the fence',a,b),a,b)).toBe(
24+
'BROWN FOX JUMP OVER THE FENCE'
25+
)
26+
})
27+
})

0 commit comments

Comments
(0)