-
Notifications
You must be signed in to change notification settings - Fork 19.6k
/
Copy pathPlayfairCipher.java
128 lines (118 loc) · 4.18 KB
/
PlayfairCipher.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com.thealgorithms.ciphers;
public class PlayfairCipher {
private char[][] matrix;
private String key;
public PlayfairCipher(String key) {
this.key = key;
generateMatrix();
}
public String encrypt(String plaintext) {
plaintext = prepareText(plaintext.replace("J", "I"));
StringBuilder ciphertext = new StringBuilder();
for (int i = 0; i < plaintext.length(); i += 2) {
char char1 = plaintext.charAt(i);
char char2 = plaintext.charAt(i + 1);
int[] pos1 = findPosition(char1);
int[] pos2 = findPosition(char2);
int row1 = pos1[0];
int col1 = pos1[1];
int row2 = pos2[0];
int col2 = pos2[1];
if (row1 == row2) {
ciphertext.append(matrix[row1][(col1 + 1) % 5]);
ciphertext.append(matrix[row2][(col2 + 1) % 5]);
} else if (col1 == col2) {
ciphertext.append(matrix[(row1 + 1) % 5][col1]);
ciphertext.append(matrix[(row2 + 1) % 5][col2]);
} else {
ciphertext.append(matrix[row1][col2]);
ciphertext.append(matrix[row2][col1]);
}
}
return ciphertext.toString();
}
public String decrypt(String ciphertext) {
StringBuilder plaintext = new StringBuilder();
for (int i = 0; i < ciphertext.length(); i += 2) {
char char1 = ciphertext.charAt(i);
char char2 = ciphertext.charAt(i + 1);
int[] pos1 = findPosition(char1);
int[] pos2 = findPosition(char2);
int row1 = pos1[0];
int col1 = pos1[1];
int row2 = pos2[0];
int col2 = pos2[1];
if (row1 == row2) {
plaintext.append(matrix[row1][(col1 + 4) % 5]);
plaintext.append(matrix[row2][(col2 + 4) % 5]);
} else if (col1 == col2) {
plaintext.append(matrix[(row1 + 4) % 5][col1]);
plaintext.append(matrix[(row2 + 4) % 5][col2]);
} else {
plaintext.append(matrix[row1][col2]);
plaintext.append(matrix[row2][col1]);
}
}
return plaintext.toString();
}
private void generateMatrix() {
String keyWithoutDuplicates = removeDuplicateChars(key + "ABCDEFGHIKLMNOPQRSTUVWXYZ");
matrix = new char[5][5];
int index = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
matrix[i][j] = keyWithoutDuplicates.charAt(index);
index++;
}
}
}
private String removeDuplicateChars(String str) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
if (result.indexOf(String.valueOf(str.charAt(i))) == -1) {
result.append(str.charAt(i));
}
}
return result.toString();
}
private String prepareText(String text) {
text = text.toUpperCase().replaceAll("[^A-Z]", "");
StringBuilder preparedText = new StringBuilder();
char prevChar = '\0';
for (char c : text.toCharArray()) {
if (c != prevChar) {
preparedText.append(c);
prevChar = c;
} else {
preparedText.append('X').append(c);
prevChar = '\0';
}
}
if (preparedText.length() % 2 != 0) {
preparedText.append('X');
}
return preparedText.toString();
}
private int[] findPosition(char c) {
int[] pos = new int[2];
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (matrix[i][j] == c) {
pos[0] = i;
pos[1] = j;
return pos;
}
}
}
return pos;
}
public void printMatrix() {
System.out.println("\nPlayfair Cipher Matrix:");
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
}