1// Aim: Program to perform Playfair cipher (Playfair Cipher).
2import java.util.*;
3
4public class cipher2 {
5
6 private static char[][] matrix = new char[5][5];
7
8 private static void generateKeyMatrix(String key) {
9 key = key.toUpperCase().replaceAll("[^A-Z]", "").replace("J", "I");
10 StringBuilder sb = new StringBuilder();
11 Set<Character> used = new HashSet<>();
12 for (char c : key.toCharArray()) {
13 if (!used.contains(c)) {
14 sb.append(c);
15 used.add(c);
16 }
17 }
18 for (char c = 'A'; c <= 'Z'; c++) {
19 if (c != 'J' && !used.contains(c)) {
20 sb.append(c);
21 used.add(c);
22 }
23 }
24 int k = 0;
25 for (int i = 0; i < 5; i++)
26 for (int j = 0; j < 5; j++)
27 matrix[i][j] = sb.charAt(k++);
28 }
29
30 private static int[] findPosition(char c) {
31 if (c == 'J') c = 'I';
32 for (int i = 0; i < 5; i++)
33 for (int j = 0; j < 5; j++)
34 if (matrix[i][j] == c)
35 return new int[]{i, j};
36 return null;
37 }
38
39 private static String prepareText(String text) {
40 text = text.toUpperCase().replaceAll("[^A-Z]", "").replace("J", "I");
41 StringBuilder sb = new StringBuilder();
42 int i = 0;
43 while (i < text.length()) {
44 char a = text.charAt(i);
45 char b = (i + 1 < text.length()) ? text.charAt(i + 1) : 'X';
46 if (a == b) {
47 sb.append(a).append('X');
48 i++;
49 } else {
50 sb.append(a).append(b);
51 i += 2;
52 }
53 }
54 if (sb.length() % 2 != 0)
55 sb.append('X');
56 return sb.toString();
57 }
58
59 public static String playfairEncrypt(String text, String key) {
60 generateKeyMatrix(key);
61 text = prepareText(text);
62 StringBuilder cipher = new StringBuilder();
63 for (int i = 0; i < text.length(); i += 2) {
64 int[] pos1 = findPosition(text.charAt(i));
65 int[] pos2 = findPosition(text.charAt(i + 1));
66 if (pos1[0] == pos2[0]) { // Same row
67 cipher.append(matrix[pos1[0]][(pos1[1] + 1) % 5]);
68 cipher.append(matrix[pos2[0]][(pos2[1] + 1) % 5]);
69 } else if (pos1[1] == pos2[1]) { // Same column
70 cipher.append(matrix[(pos1[0] + 1) % 5][pos1[1]]);
71 cipher.append(matrix[(pos2[0] + 1) % 5][pos2[1]]);
72 } else { // Rectangle swap
73 cipher.append(matrix[pos1[0]][pos2[1]]);
74 cipher.append(matrix[pos2[0]][pos1[1]]);
75 }
76 }
77 return cipher.toString();
78 }
79
80 public static String playfairDecrypt(String text, String key) {
81 generateKeyMatrix(key);
82 text = prepareText(text);
83 StringBuilder plain = new StringBuilder();
84 for (int i = 0; i < text.length(); i += 2) {
85 int[] pos1 = findPosition(text.charAt(i));
86 int[] pos2 = findPosition(text.charAt(i + 1));
87 if (pos1[0] == pos2[0]) { // Same row
88 plain.append(matrix[pos1[0]][(pos1[1] + 4) % 5]);
89 plain.append(matrix[pos2[0]][(pos2[1] + 4) % 5]);
90 } else if (pos1[1] == pos2[1]) { // Same column
91 plain.append(matrix[(pos1[0] + 4) % 5][pos1[1]]);
92 plain.append(matrix[(pos2[0] + 4) % 5][pos2[1]]);
93 } else { // Rectangle swap
94 plain.append(matrix[pos1[0]][pos2[1]]);
95 plain.append(matrix[pos2[0]][pos1[1]]);
96 }
97 }
98 return plain.toString();
99 }
100
101 public static String railencrypt(String text, int key) {
102 if (key <= 1) return text;
103 StringBuilder[] rail = new StringBuilder[key];
104 for (int i = 0; i < key; i++) rail[i] = new StringBuilder();
105
106 int dir = 1, row = 0;
107 for (char c : text.toCharArray()) {
108 rail[row].append(c);
109 row += dir;
110 if (row == 0 || row == key - 1) dir *= -1;
111 }
112
113 StringBuilder result = new StringBuilder();
114 for (StringBuilder sb : rail) result.append(sb);
115 return result.toString();
116 }
117
118 public static String raildecrypt(String cipher, int key) {
119 if (key <= 1) return cipher;
120 int len = cipher.length();
121 boolean[][] mark = new boolean[key][len];
122
123 int dir = 1, row = 0;
124 for (int i = 0; i < len; i++) {
125 mark[row][i] = true;
126 row += dir;
127 if (row == 0 || row == key - 1) dir *= -1;
128 }
129
130 char[] result = new char[len];
131 int idx = 0;
132 for (int i = 0; i < key; i++) {
133 for (int j = 0; j < len; j++) {
134 if (mark[i][j] && idx < len) {
135 result[j] = cipher.charAt(idx++);
136 }
137 }
138 }
139
140 StringBuilder plain = new StringBuilder();
141 row = 0; dir = 1;
142 for (int i = 0; i < len; i++) {
143 plain.append(result[i]);
144 row += dir;
145 if (row == 0 || row == key - 1) dir *= -1;
146 }
147 return plain.toString();
148 }
149
150 public static void main(String[] args) {
151 Scanner sc = new Scanner(System.in);
152 int ch;
153 do{
154 System.out.println("1. playfair cipher\n2. railfence cipher\n3. exit\nchoose an option: \n");
155 ch = sc.nextInt();
156 sc.nextLine();
157 switch (ch) {
158 case 1:
159 System.out.println("Enter key: ");
160 String key = sc.nextLine();
161 System.out.println("Enter plaintext: ");
162 String plaintext = sc.nextLine();
163 String encrypted = playfairEncrypt(plaintext, key);
164 System.out.println("Encrypted text: " + encrypted);
165 String decrypted = playfairDecrypt(encrypted, key);
166 System.out.println("Decrypted text: " + decrypted);
167 break;
168
169 case 2:
170 System.out.println("Enter plaintext: ");
171 String railText = sc.nextLine();
172 System.out.println("Enter key: ");
173 int railKey = sc.nextInt();
174 sc.nextLine();
175 String railEncrypted = railencrypt(railText, railKey);
176 System.out.println("Encrypted text: " + railEncrypted);
177 String railDecrypted = raildecrypt(railEncrypted, railKey);
178 System.out.println("Decrypted text: " + railDecrypted);
179 break;
180
181 case 3:
182 System.out.println("Exiting...");
183 break;
184
185 default:
186 System.out.println("Invalid option.");
187 break;
188 }
189 }while (ch!=3);
190 }
191}
192