Skip to content

Commit f80850b

Browse files
authored
Add Junit tests for AffineCipher.java, improve documentation (TheAlgorithms#5598)
1 parent 99d7f80 commit f80850b

File tree

3 files changed

+80
-11
lines changed

3 files changed

+80
-11
lines changed

DIRECTORY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,7 @@
637637
* [A5KeyStreamGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/A5KeyStreamGeneratorTest.java)
638638
* [LFSRTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java)
639639
* [AESEncryptionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AESEncryptionTest.java)
640+
* [AffineCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AffineCipherTest.java)
640641
* [AutokeyTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AutokeyTest.java)
641642
* [BlowfishTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java)
642643
* [CaesarTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/CaesarTest.java)

src/main/java/com/thealgorithms/ciphers/AffineCipher.java

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
package com.thealgorithms.ciphers;
22

3+
/**
4+
* The AffineCipher class implements the Affine cipher, a type of monoalphabetic substitution cipher.
5+
* It encrypts and decrypts messages using a linear transformation defined by the formula:
6+
*
7+
* E(x) = (a * x + b) mod m
8+
* D(y) = a^-1 * (y - b) mod m
9+
*
10+
* where:
11+
* - E(x) is the encrypted character,
12+
* - D(y) is the decrypted character,
13+
* - a is the multiplicative key (must be coprime to m),
14+
* - b is the additive key,
15+
* - x is the index of the plaintext character,
16+
* - y is the index of the ciphertext character,
17+
* - m is the size of the alphabet (26 for the English alphabet).
18+
*
19+
* The class provides methods for encrypting and decrypting messages, as well as a main method to demonstrate its usage.
20+
*/
321
final class AffineCipher {
422
private AffineCipher() {
523
}
@@ -8,45 +26,56 @@ private AffineCipher() {
826
static int a = 17;
927
static int b = 20;
1028

29+
/**
30+
* Encrypts a message using the Affine cipher.
31+
*
32+
* @param msg the plaintext message as a character array
33+
* @return the encrypted ciphertext
34+
*/
1135
static String encryptMessage(char[] msg) {
12-
/// Cipher Text initially empty
36+
// Cipher Text initially empty
1337
String cipher = "";
1438
for (int i = 0; i < msg.length; i++) {
1539
// Avoid space to be encrypted
16-
/* applying encryption formula ( a x + b ) mod m
40+
/* applying encryption formula ( a * x + b ) mod m
1741
{here x is msg[i] and m is 26} and added 'A' to
18-
bring it in range of ascii alphabet[ 65-90 | A-Z ] */
42+
bring it in the range of ASCII alphabet [65-90 | A-Z] */
1943
if (msg[i] != ' ') {
20-
cipher = cipher + (char) ((((a * (msg[i] - 'A')) + b) % 26) + 'A');
44+
cipher += (char) ((((a * (msg[i] - 'A')) + b) % 26) + 'A');
2145
} else { // else simply append space character
2246
cipher += msg[i];
2347
}
2448
}
2549
return cipher;
2650
}
2751

52+
/**
53+
* Decrypts a ciphertext using the Affine cipher.
54+
*
55+
* @param cipher the ciphertext to decrypt
56+
* @return the decrypted plaintext message
57+
*/
2858
static String decryptCipher(String cipher) {
2959
String msg = "";
3060
int aInv = 0;
31-
int flag = 0;
61+
int flag;
3262

33-
// Find a^-1 (the multiplicative inverse of a
34-
// in the group of integers modulo m.)
63+
// Find a^-1 (the multiplicative inverse of a in the group of integers modulo m.)
3564
for (int i = 0; i < 26; i++) {
3665
flag = (a * i) % 26;
3766

38-
// Check if (a*i)%26 == 1,
67+
// Check if (a * i) % 26 == 1,
3968
// then i will be the multiplicative inverse of a
4069
if (flag == 1) {
4170
aInv = i;
4271
}
4372
}
4473
for (int i = 0; i < cipher.length(); i++) {
45-
/*Applying decryption formula a^-1 ( x - b ) mod m
74+
/* Applying decryption formula a^-1 * (x - b) mod m
4675
{here x is cipher[i] and m is 26} and added 'A'
47-
to bring it in range of ASCII alphabet[ 65-90 | A-Z ] */
76+
to bring it in the range of ASCII alphabet [65-90 | A-Z] */
4877
if (cipher.charAt(i) != ' ') {
49-
msg = msg + (char) (((aInv * ((cipher.charAt(i) + 'A' - b)) % 26)) + 'A');
78+
msg += (char) (((aInv * ((cipher.charAt(i) - 'A') - b + 26)) % 26) + 'A');
5079
} else { // else simply append space character
5180
msg += cipher.charAt(i);
5281
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.thealgorithms.ciphers;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
public class AffineCipherTest {
8+
9+
@Test
10+
public void testEncryptMessage() {
11+
String plaintext = "AFFINE CIPHER";
12+
char[] msg = plaintext.toCharArray();
13+
String expectedCiphertext = "UBBAHK CAPJKX"; // Expected ciphertext after encryption
14+
15+
String actualCiphertext = AffineCipher.encryptMessage(msg);
16+
assertEquals(expectedCiphertext, actualCiphertext, "The encryption result should match the expected ciphertext.");
17+
}
18+
19+
@Test
20+
public void testEncryptDecrypt() {
21+
String plaintext = "HELLO WORLD";
22+
char[] msg = plaintext.toCharArray();
23+
24+
String ciphertext = AffineCipher.encryptMessage(msg);
25+
String decryptedText = AffineCipher.decryptCipher(ciphertext);
26+
27+
assertEquals(plaintext, decryptedText, "Decrypted text should match the original plaintext.");
28+
}
29+
30+
@Test
31+
public void testSpacesHandledInEncryption() {
32+
String plaintext = "HELLO WORLD";
33+
char[] msg = plaintext.toCharArray();
34+
String expectedCiphertext = "JKZZY EYXZT";
35+
36+
String actualCiphertext = AffineCipher.encryptMessage(msg);
37+
assertEquals(expectedCiphertext, actualCiphertext, "The encryption should handle spaces correctly.");
38+
}
39+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy