forked from TheAlgorithms/Java
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAffineCipher.java
98 lines (88 loc) · 3.31 KB
/
AffineCipher.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package com.thealgorithms.ciphers;
/**
* The AffineCipher class implements the Affine cipher, a type of monoalphabetic substitution cipher.
* It encrypts and decrypts messages using a linear transformation defined by the formula:
*
* E(x) = (a * x + b) mod m
* D(y) = a^-1 * (y - b) mod m
*
* where:
* - E(x) is the encrypted character,
* - D(y) is the decrypted character,
* - a is the multiplicative key (must be coprime to m),
* - b is the additive key,
* - x is the index of the plaintext character,
* - y is the index of the ciphertext character,
* - m is the size of the alphabet (26 for the English alphabet).
*
* The class provides methods for encrypting and decrypting messages, as well as a main method to demonstrate its usage.
*/
final class AffineCipher {
private AffineCipher() {
}
// Key values of a and b
static int a = 17;
static int b = 20;
/**
* Encrypts a message using the Affine cipher.
*
* @param msg the plaintext message as a character array
* @return the encrypted ciphertext
*/
static String encryptMessage(char[] msg) {
// Cipher Text initially empty
StringBuilder cipher = new StringBuilder();
for (int i = 0; i < msg.length; i++) {
// Avoid space to be encrypted
/* applying encryption formula ( a * x + b ) mod m
{here x is msg[i] and m is 26} and added 'A' to
bring it in the range of ASCII alphabet [65-90 | A-Z] */
if (msg[i] != ' ') {
cipher.append((char) ((((a * (msg[i] - 'A')) + b) % 26) + 'A'));
} else { // else simply append space character
cipher.append(msg[i]);
}
}
return cipher.toString();
}
/**
* Decrypts a ciphertext using the Affine cipher.
*
* @param cipher the ciphertext to decrypt
* @return the decrypted plaintext message
*/
static String decryptCipher(String cipher) {
StringBuilder msg = new StringBuilder();
int aInv = 0;
int flag;
// Find a^-1 (the multiplicative inverse of a in the group of integers modulo m.)
for (int i = 0; i < 26; i++) {
flag = (a * i) % 26;
// Check if (a * i) % 26 == 1,
// then i will be the multiplicative inverse of a
if (flag == 1) {
aInv = i;
}
}
for (int i = 0; i < cipher.length(); i++) {
/* Applying decryption formula a^-1 * (x - b) mod m
{here x is cipher[i] and m is 26} and added 'A'
to bring it in the range of ASCII alphabet [65-90 | A-Z] */
if (cipher.charAt(i) != ' ') {
msg.append((char) (((aInv * ((cipher.charAt(i) - 'A') - b + 26)) % 26) + 'A'));
} else { // else simply append space character
msg.append(cipher.charAt(i));
}
}
return msg.toString();
}
// Driver code
public static void main(String[] args) {
String msg = "AFFINE CIPHER";
// Calling encryption function
String cipherText = encryptMessage(msg.toCharArray());
System.out.println("Encrypted Message is : " + cipherText);
// Calling Decryption function
System.out.println("Decrypted Message is: " + decryptCipher(cipherText));
}
}