Skip to content

Commit 9bef5a1

Browse files
authored
Add Playfair Cipher (TheAlgorithms#4988)
1 parent a7d140a commit 9bef5a1

File tree

3 files changed

+169
-0
lines changed

3 files changed

+169
-0
lines changed

DIRECTORY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
* [NonRepeatingNumberFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java)
2828
* [NumbersDifferentSigns](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java)
2929
* [ReverseBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java)
30+
* [SetKthBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SetKthBit.java)
3031
* [SingleBitOperations](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java)
3132
* ciphers
3233
* a5
@@ -44,6 +45,7 @@
4445
* [ColumnarTranspositionCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java)
4546
* [DES](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/DES.java)
4647
* [HillCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/HillCipher.java)
48+
* [PlayfairCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java)
4749
* [Polybius](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Polybius.java)
4850
* [ProductCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ProductCipher.java)
4951
* [RSA](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/RSA.java)
@@ -585,13 +587,15 @@
585587
* [NonRepeatingNumberFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java)
586588
* [NumbersDifferentSignsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java)
587589
* [ReverseBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java)
590+
* [SetKthBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SetKthBitTest.java)
588591
* [SingleBitOperationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java)
589592
* ciphers
590593
* a5
591594
* [LFSRTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java)
592595
* [BlowfishTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java)
593596
* [CaesarTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/CaesarTest.java)
594597
* [DESTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/DESTest.java)
598+
* [PlayfairTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java)
595599
* [PolybiusTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PolybiusTest.java)
596600
* [RSATest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/RSATest.java)
597601
* [SimpleSubCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java)
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package com.thealgorithms.ciphers;
2+
3+
public class PlayfairCipher {
4+
5+
private char[][] matrix;
6+
private String key;
7+
8+
public PlayfairCipher(String key) {
9+
this.key = key;
10+
generateMatrix();
11+
}
12+
13+
public String encrypt(String plaintext) {
14+
plaintext = prepareText(plaintext.replace("J", "I"));
15+
StringBuilder ciphertext = new StringBuilder();
16+
for (int i = 0; i < plaintext.length(); i += 2) {
17+
char char1 = plaintext.charAt(i);
18+
char char2 = plaintext.charAt(i + 1);
19+
int[] pos1 = findPosition(char1);
20+
int[] pos2 = findPosition(char2);
21+
int row1 = pos1[0];
22+
int col1 = pos1[1];
23+
int row2 = pos2[0];
24+
int col2 = pos2[1];
25+
if (row1 == row2) {
26+
ciphertext.append(matrix[row1][(col1 + 1) % 5]);
27+
ciphertext.append(matrix[row2][(col2 + 1) % 5]);
28+
} else if (col1 == col2) {
29+
ciphertext.append(matrix[(row1 + 1) % 5][col1]);
30+
ciphertext.append(matrix[(row2 + 1) % 5][col2]);
31+
} else {
32+
ciphertext.append(matrix[row1][col2]);
33+
ciphertext.append(matrix[row2][col1]);
34+
}
35+
}
36+
return ciphertext.toString();
37+
}
38+
39+
public String decrypt(String ciphertext) {
40+
StringBuilder plaintext = new StringBuilder();
41+
for (int i = 0; i < ciphertext.length(); i += 2) {
42+
char char1 = ciphertext.charAt(i);
43+
char char2 = ciphertext.charAt(i + 1);
44+
int[] pos1 = findPosition(char1);
45+
int[] pos2 = findPosition(char2);
46+
int row1 = pos1[0];
47+
int col1 = pos1[1];
48+
int row2 = pos2[0];
49+
int col2 = pos2[1];
50+
if (row1 == row2) {
51+
plaintext.append(matrix[row1][(col1 + 4) % 5]);
52+
plaintext.append(matrix[row2][(col2 + 4) % 5]);
53+
} else if (col1 == col2) {
54+
plaintext.append(matrix[(row1 + 4) % 5][col1]);
55+
plaintext.append(matrix[(row2 + 4) % 5][col2]);
56+
} else {
57+
plaintext.append(matrix[row1][col2]);
58+
plaintext.append(matrix[row2][col1]);
59+
}
60+
}
61+
return plaintext.toString();
62+
}
63+
64+
private void generateMatrix() {
65+
String keyWithoutDuplicates = removeDuplicateChars(key + "ABCDEFGHIKLMNOPQRSTUVWXYZ");
66+
matrix = new char[5][5];
67+
int index = 0;
68+
for (int i = 0; i < 5; i++) {
69+
for (int j = 0; j < 5; j++) {
70+
matrix[i][j] = keyWithoutDuplicates.charAt(index);
71+
index++;
72+
}
73+
}
74+
}
75+
76+
private String removeDuplicateChars(String str) {
77+
StringBuilder result = new StringBuilder();
78+
for (int i = 0; i < str.length(); i++) {
79+
if (result.indexOf(String.valueOf(str.charAt(i))) == -1) {
80+
result.append(str.charAt(i));
81+
}
82+
}
83+
return result.toString();
84+
}
85+
86+
private String prepareText(String text) {
87+
text = text.toUpperCase().replaceAll("[^A-Z]", "");
88+
StringBuilder preparedText = new StringBuilder();
89+
char prevChar = '\0';
90+
for (char c : text.toCharArray()) {
91+
if (c != prevChar) {
92+
preparedText.append(c);
93+
prevChar = c;
94+
} else {
95+
preparedText.append('X').append(c);
96+
prevChar = '\0';
97+
}
98+
}
99+
if (preparedText.length() % 2 != 0) {
100+
preparedText.append('X');
101+
}
102+
return preparedText.toString();
103+
}
104+
105+
private int[] findPosition(char c) {
106+
int[] pos = new int[2];
107+
for (int i = 0; i < 5; i++) {
108+
for (int j = 0; j < 5; j++) {
109+
if (matrix[i][j] == c) {
110+
pos[0] = i;
111+
pos[1] = j;
112+
return pos;
113+
}
114+
}
115+
}
116+
return pos;
117+
}
118+
119+
public void printMatrix() {
120+
System.out.println("\nPlayfair Cipher Matrix:");
121+
for (int i = 0; i < 5; i++) {
122+
for (int j = 0; j < 5; j++) {
123+
System.out.print(matrix[i][j] + " ");
124+
}
125+
System.out.println();
126+
}
127+
}
128+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.thealgorithms.ciphers;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
public class PlayfairTest {
8+
9+
@Test
10+
public void testEncryption() {
11+
PlayfairCipher playfairCipher = new PlayfairCipher("KEYWORD");
12+
13+
String plaintext = "HELLO";
14+
String encryptedText = playfairCipher.encrypt(plaintext);
15+
assertEquals("GYIZSC", encryptedText);
16+
}
17+
18+
@Test
19+
public void testDecryption() {
20+
PlayfairCipher playfairCipher = new PlayfairCipher("KEYWORD");
21+
22+
String encryptedText = "UDRIYP";
23+
String decryptedText = playfairCipher.decrypt(encryptedText);
24+
assertEquals("NEBFVH", decryptedText);
25+
}
26+
27+
@Test
28+
public void testEncryptionAndDecryption() {
29+
PlayfairCipher playfairCipher = new PlayfairCipher("KEYWORD");
30+
31+
String plaintext = "PLAYFAIR";
32+
String encryptedText = playfairCipher.encrypt(plaintext);
33+
String decryptedText = playfairCipher.decrypt(encryptedText);
34+
35+
assertEquals(plaintext, decryptedText);
36+
}
37+
}

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