Add Playfair Cipher (#4988)

This commit is contained in:
Govind Gupta
2024-01-03 18:44:38 +05:30
committed by GitHub
parent a7d140a43e
commit 9bef5a169c
3 changed files with 169 additions and 0 deletions

View File

@ -0,0 +1,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();
}
}
}