cipher.java
219 linesjava
DOWNLOAD
1// Aim: Program to perform Substitution cipher (Substitution Cipher).
2import java.util.*;
3import java.util.Scanner;
4
5public class cipher {
6
7    public static String encrypt(String text, int shift) {
8        StringBuilder result = new StringBuilder();
9        for(char c : text.toCharArray()){
10            if(Character.isUpperCase(c)){
11                result.append((char) (((c-'A'+shift)%26)+'A'));
12            }else if(Character.isLowerCase(c)) {
13                result.append((char) (((c-'a'+shift)%26)+'a'));
14            }else{
15                result.append(c);
16            }
17        }
18        return result.toString();
19    }
20
21    public static String decrypt(String text, int shift) {
22        return encrypt(text,26-(shift%26));
23    }
24    
25    private static String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
26    
27    public static String monoencrypt(String plainText, String key) {
28        plainText = plainText.toUpperCase();
29        StringBuilder cipherText = new StringBuilder();
30        for (char c : plainText.toCharArray()) {
31            int idx = ALPHABET.indexOf(c);
32            if (idx!=-1){
33                cipherText.append(key.charAt(idx));
34            }else{
35                cipherText.append(c);
36            }
37        }
38        return cipherText.toString();
39    }
40
41    public static String monodecrypt(String cipherText, String key) {
42        cipherText = cipherText.toUpperCase();
43        StringBuilder plainText = new StringBuilder();
44        for (char c : cipherText.toCharArray()) {
45            int idx = key.indexOf(c);
46            if(idx != -1){
47                plainText.append(ALPHABET.charAt(idx));
48            }else{
49                plainText.append(c);
50            }
51        }
52        return plainText.toString();
53    }
54    
55    public static int modInverse(int a, int m) {
56    	a = a % m;
57    	for (int x = 1; x < m; x++) {
58      		if ((a * x) % m == 1)
59        	return x;
60    	}
61    	return -1;
62    }
63    
64    
65    public static String hillEncrypt(String plaintext, int[][] keyMatrix) {
66    	plaintext = plaintext.toUpperCase();
67    	int[] vector = new int[3];
68    	for (int i = 0; i < 3; i++) {
69      	vector[i] = plaintext.charAt(i) - 'A';
70    	}
71
72    	int[] result = new int[3];
73    	for (int i = 0; i < 3; i++) {
74      		result[i] = 0;
75      		for (int j = 0; j < 3; j++) {
76        		result[i] += keyMatrix[i][j] * vector[j];
77      		}
78      		result[i] %= 26;
79    	}
80
81    	StringBuilder encrypted = new StringBuilder();
82    	for (int val : result) {
83      	encrypted.append((char) (val + 'A'));
84    	}
85    	return encrypted.toString();
86     }
87    
88    public static int determinant(int[][] m) {
89    	return m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1])
90        	- m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0])
91        	+ m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
92    }
93    
94    public static int[][] adjugate(int[][] m) {
95    	int[][] adj = new int[3][3];
96
97    	adj[0][0] = (m[1][1] * m[2][2] - m[1][2] * m[2][1]);
98    	adj[0][1] = -(m[1][0] * m[2][2] - m[1][2] * m[2][0]);
99    	adj[0][2] = (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
100
101    	adj[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]);
102    	adj[1][1] = (m[0][0] * m[2][2] - m[0][2] * m[2][0]);
103    	adj[1][2] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]);
104
105    	adj[2][0] = (m[0][1] * m[1][2] - m[0][2] * m[1][1]);
106    	adj[2][1] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]);
107    	adj[2][2] = (m[0][0] * m[1][1] - m[0][1] * m[1][0]);
108
109    	int[][] transpose = new int[3][3];
110    	for (int i = 0; i < 3; i++)
111      		for (int j = 0; j < 3; j++)
112        	transpose[i][j] = adj[j][i];
113
114    		return transpose;
115    }
116  
117    public static String hillDecrypt(String ciphertext, int[][] keyMatrix) {
118    	int det = determinant(keyMatrix);
119    	int detInv = modInverse(det % 26, 26);
120    	if (detInv == -1)
121      	return "Key not invertible. Decryption failed.";
122
123    	int[][] adj = adjugate(keyMatrix);
124    	int[][] inv = new int[3][3];
125
126    	for (int i = 0; i < 3; i++)
127      		for (int j = 0; j < 3; j++) {
128        		inv[i][j] = (adj[i][j] * detInv) % 26;
129        		if (inv[i][j] < 0)
130          		inv[i][j] += 26;
131      		}
132
133    		ciphertext = ciphertext.toUpperCase();
134    		int[] vector = new int[3];
135    		for (int i = 0; i < 3; i++) {
136      			vector[i] = ciphertext.charAt(i) - 'A';
137   		}
138
139    		int[] result = new int[3];
140    		for (int i = 0; i < 3; i++) {
141      			result[i] = 0;
142     			 for (int j = 0; j < 3; j++) {
143        			result[i] += inv[i][j] * vector[j];
144      			 }
145      			 result[i] %= 26;
146    		}
147
148    		StringBuilder decrypted = new StringBuilder();
149    		for (int val : result) {
150      			decrypted.append((char) (val + 'A'));
151    		}
152    		return decrypted.toString();
153  }
154    
155    
156    public static void main(String[] args) {
157        Scanner sc = new Scanner(System.in);
158        int ch;
159        do{
160        	System.out.println("\n--- Cipher Menu ---\n1. Caesar Cipher\n2. Substitution Cipher\n3. Hill Cipher \n4. Exit\nChoose option: \n");
161      		
162      		ch = sc.nextInt();
163      		sc.nextLine();
164      		switch(ch){
165      			case 1 :
166      				System.out.print("Enter text: ");
167        			String text = sc.nextLine();
168        			System.out.print("Enter shift: ");
169        			int shift = sc.nextInt();
170        			String encrypted = encrypt(text, shift);
171        			String decrypted = decrypt(encrypted, shift);
172        			System.out.println("Encrypted: " + encrypted);
173        			System.out.println("Decrypted: " + decrypted);
174        			break;
175        		case 2 :
176        			System.out.print("Enter key (26 unique uppercase letters): ");
177        			String key = sc.nextLine().toUpperCase();
178        			System.out.print("Enter plain text: ");
179        			String plainText = sc.nextLine();
180        			String monoencrypted = monoencrypt(plainText, key);
181        			String monodecrypted = monodecrypt(monoencrypted, key);
182        			System.out.println("Encrypted: " + monoencrypted);
183        			System.out.println("Decrypted: " + monodecrypted);
184        			break;
185        		case 3 :
186        			System.out.print("Enter 9-letter key: ");
187          			String keyStr = sc.nextLine().toUpperCase();
188          			if (keyStr.length() != 9) {
189            				System.out.println("Key must be 9 letters.");
190            			break;
191          			}
192          			int[][] matrix = new int[3][3];
193          			for (int i = 0; i < 9; i++)
194            				matrix[i / 3][i % 3] = keyStr.charAt(i) - 'A';
195
196          			System.out.print("Enter 3-letter plaintext: ");
197          			String plain = sc.nextLine().toUpperCase();
198          			if (plain.length() != 3) {
199            			System.out.println("Plaintext must be 3 letters.");
200            			break;
201          			}
202
203          			String hillEnc = hillEncrypt(plain, matrix);
204          			String hillDec = hillDecrypt(hillEnc, matrix);
205          			System.out.println("Encrypted: " + hillEnc);
206          			System.out.println("Decrypted: " + hillDec);
207          			break;
208        		case 4:
209          			System.out.println("Exiting.");
210          			break;
211
212        		default:
213          			System.out.println("Invalid option.");
214      		}
215        }while(ch != 4);
216        sc.close();  
217    }
218}
219