Decryption
- Playfair Decryption
import java.util.*;
public class PlayfairCipher {
// Method to generate the 5x5 key square
public static char[][] generateKeyTable(String key) {
key = key.toLowerCase().replace("j", "i");
Set<Character> set = new LinkedHashSet<>();
for (char c : key.toCharArray()) {
if (c >= 'a' && c <= 'z') {
set.add(c);
}
}
for (char c = 'a'; c <= 'z'; c++) {
if (c != 'j' && !set.contains(c)) {
set.add(c);
}
}
char[][] keyTable = new char[5][5];
int index = 0;
for (char c : set) {
keyTable[index / 5][index % 5] = c;
index++;
}
return keyTable;
}
// Method to find the position of a character in the key table
public static int[] search(char[][] keyTable, char ch) {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (keyTable[i][j] == ch) {
return new int[]{i, j};
}
}
}
return null;
}
// Method to decrypt the ciphertext
public static String decrypt(String ciphertext, String key) {
char[][] keyTable = generateKeyTable(key);
StringBuilder decrypted = new StringBuilder();
ciphertext = ciphertext.replace(" ", "").toLowerCase();
for (int i = 0; i < ciphertext.length(); i += 2) {
char first = ciphertext.charAt(i);
char second = ciphertext.charAt(i + 1);
int[] pos1 = search(keyTable, first);
int[] pos2 = search(keyTable, second);
if (pos1[0] == pos2[0]) { // Same row
decrypted.append(keyTable[pos1[0]][(pos1[1] + 4) % 5]);
decrypted.append(keyTable[pos2[0]][(pos2[1] + 4) % 5]);
} else if (pos1[1] == pos2[1]) { // Same column
decrypted.append(keyTable[(pos1[0] + 4) % 5][pos1[1]]);
decrypted.append(keyTable[(pos2[0] + 4) % 5][pos2[1]]);
} else { // Rectangle
decrypted.append(keyTable[pos1[0]][pos2[1]]);
decrypted.append(keyTable[pos2[0]][pos1[1]]);
}
}
return decrypted.toString();
}
public static void main(String[] args) {
String ciphertext = "GQIHPA LXIQTX";
String key = "INFORMATION";
String decryptedMessage = decrypt(ciphertext, key);
System.out.println("Decrypted Message: " + decryptedMessage);
}
}
- Hill Climb Decryption
public class HillCipher2x2Decrypt {
static final int MOD = 26;
// Converts a character to a number (A=0, ..., Z=25)
static int charToNum(char c) {
return c - 'A';
}
// Converts a number to a character
static char numToChar(int n) {
return (char)((n + MOD) % MOD + 'A');
}
// Finds modular inverse of a number modulo MOD
static int modInverse(int a) {
a = (a % MOD + MOD) % MOD;
for (int x = 1; x < MOD; x++) {
if ((a * x) % MOD == 1) return x;
}
throw new ArithmeticException("No modular inverse exists for determinant.");
}
// Returns inverse of a 2x2 matrix modulo MOD
static int[][] inverseMatrix(int[][] matrix) {
int a = matrix[0][0], b = matrix[0][1];
int c = matrix[1][0], d = matrix[1][1];
int det = (a * d - b * c) % MOD;
int invDet = modInverse(det);
int[][] inv = new int[2][2];
inv[0][0] = (d * invDet) % MOD;
inv[0][1] = (-b * invDet) % MOD;
inv[1][0] = (-c * invDet) % MOD;
inv[1][1] = (a * invDet) % MOD;
// Make sure all elements are positive
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
inv[i][j] = (inv[i][j] + MOD) % MOD;
}
}
return inv;
}
// Decrypts the ciphertext using the inverse of the key matrix
static String decrypt(String ciphertext, int[][] key) {
int[][] inverseKey = inverseMatrix(key);
StringBuilder plaintext = new StringBuilder();
for (int i = 0; i < ciphertext.length(); i += 2) {
int x = charToNum(ciphertext.charAt(i));
int y = charToNum(ciphertext.charAt(i + 1));
int p1 = (inverseKey[0][0] * x + inverseKey[0][1] * y) % MOD;
int p2 = (inverseKey[1][0] * x + inverseKey[1][1] * y) % MOD;
plaintext.append(numToChar(p1));
plaintext.append(numToChar(p2));
}
return plaintext.toString();
}
public static void main(String[] args) {
// Key matrix
int[][] key = {
{5, 8},
{7, 3}
};
// Encrypted text
String ciphertext = "FPHI";
// Decrypt and display result
String decrypted = decrypt(ciphertext, key);
System.out.println("Decrypted Text: " + decrypted);
}
}