2021-10-06 14:47:44 +08:00
|
|
|
|
package Ciphers;
|
|
|
|
|
|
2021-10-29 13:19:42 +08:00
|
|
|
|
import java.util.Scanner;
|
2021-10-06 14:47:44 +08:00
|
|
|
|
|
|
|
|
|
/*
|
2021-10-29 13:19:42 +08:00
|
|
|
|
* Java Implementation of Hill Cipher
|
|
|
|
|
* Hill cipher is a polyalphabetic substitution cipher. Each letter is represented by a number belonging to the set Z26 where A=0 , B=1, ..... Z=25.
|
|
|
|
|
* To encrypt a message, each block of n letters (since matrix size is n x n) is multiplied by an invertible n × n matrix, against modulus 26.
|
|
|
|
|
* To decrypt the message, each block is multiplied by the inverse of the matrix used for encryption.
|
|
|
|
|
* The cipher key and plaintext/ciphertext are user inputs.
|
|
|
|
|
* @author Ojasva Jain
|
|
|
|
|
*/
|
2021-10-06 14:47:44 +08:00
|
|
|
|
|
2021-10-29 13:19:42 +08:00
|
|
|
|
public class HillCipher {
|
|
|
|
|
static Scanner in = new Scanner(System.in);
|
2021-10-06 14:47:44 +08:00
|
|
|
|
|
2021-10-29 13:19:42 +08:00
|
|
|
|
/* Following function encrypts the message
|
|
|
|
|
*/
|
|
|
|
|
static void encrypt(String message) {
|
|
|
|
|
message = message.toUpperCase();
|
|
|
|
|
// Get key matrix
|
|
|
|
|
System.out.println("Enter key matrix size");
|
|
|
|
|
int n = in.nextInt();
|
|
|
|
|
System.out.println("Enter Key/encryptionKey matrix ");
|
|
|
|
|
int keyMatrix[][] = new int[n][n];
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
for (int j = 0; j < n; j++) {
|
|
|
|
|
keyMatrix[i][j] = in.nextInt();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//check if det = 0
|
|
|
|
|
if (determinant(keyMatrix, n) % 26 == 0) {
|
|
|
|
|
System.out.println("Invalid key, as determinant = 0. Program Terminated");
|
|
|
|
|
return;
|
2021-10-06 14:47:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-29 13:19:42 +08:00
|
|
|
|
int[][] messageVector = new int[n][1];
|
|
|
|
|
String CipherText = "";
|
|
|
|
|
int cipherMatrix[][] = new int[n][1];
|
|
|
|
|
int j = 0;
|
|
|
|
|
while (j < message.length()) {
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
if (j >= message.length()) {
|
|
|
|
|
messageVector[i][0] = 23;
|
|
|
|
|
} else
|
|
|
|
|
messageVector[i][0] = (message.charAt(j)) % 65;
|
|
|
|
|
System.out.println(messageVector[i][0]);
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
int x, i;
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
|
cipherMatrix[i][0] = 0;
|
2021-10-06 14:47:44 +08:00
|
|
|
|
|
2021-10-29 13:19:42 +08:00
|
|
|
|
for (x = 0; x < n; x++) {
|
|
|
|
|
cipherMatrix[i][0] += keyMatrix[i][x] * messageVector[x][0];
|
|
|
|
|
}
|
|
|
|
|
System.out.println(cipherMatrix[i][0]);
|
|
|
|
|
cipherMatrix[i][0] = cipherMatrix[i][0] % 26;
|
2021-10-06 14:47:44 +08:00
|
|
|
|
}
|
2021-10-29 13:19:42 +08:00
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
|
CipherText += (char) (cipherMatrix[i][0] + 65);
|
2021-10-06 14:47:44 +08:00
|
|
|
|
}
|
2021-10-29 13:19:42 +08:00
|
|
|
|
System.out.println("Ciphertext: " + CipherText);
|
2021-10-06 14:47:44 +08:00
|
|
|
|
}
|
2021-10-29 13:19:42 +08:00
|
|
|
|
|
|
|
|
|
//Following function decrypts a message
|
|
|
|
|
static void decrypt(String message) {
|
|
|
|
|
message = message.toUpperCase();
|
|
|
|
|
// Get key matrix
|
|
|
|
|
System.out.println("Enter key matrix size");
|
|
|
|
|
int n = in.nextInt();
|
|
|
|
|
System.out.println("Enter inverseKey/decryptionKey matrix ");
|
|
|
|
|
int keyMatrix[][] = new int[n][n];
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
for (int j = 0; j < n; j++) {
|
|
|
|
|
keyMatrix[i][j] = in.nextInt();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//check if det = 0
|
|
|
|
|
if (determinant(keyMatrix, n) % 26 == 0) {
|
|
|
|
|
System.out.println("Invalid key, as determinant = 0. Program Terminated");
|
|
|
|
|
return;
|
2021-10-06 14:47:44 +08:00
|
|
|
|
}
|
2021-10-29 13:19:42 +08:00
|
|
|
|
//solving for the required plaintext message
|
|
|
|
|
int[][] messageVector = new int[n][1];
|
|
|
|
|
String PlainText = "";
|
|
|
|
|
int plainMatrix[][] = new int[n][1];
|
|
|
|
|
int j = 0;
|
|
|
|
|
while (j < message.length()) {
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
if (j >= message.length()) {
|
|
|
|
|
messageVector[i][0] = 23;
|
|
|
|
|
} else
|
|
|
|
|
messageVector[i][0] = (message.charAt(j)) % 65;
|
|
|
|
|
System.out.println(messageVector[i][0]);
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
int x, i;
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
|
plainMatrix[i][0] = 0;
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < n; x++) {
|
2021-10-06 14:47:44 +08:00
|
|
|
|
plainMatrix[i][0] += keyMatrix[i][x] * messageVector[x][0];
|
|
|
|
|
}
|
2021-10-29 13:19:42 +08:00
|
|
|
|
|
2021-10-06 14:47:44 +08:00
|
|
|
|
plainMatrix[i][0] = plainMatrix[i][0] % 26;
|
|
|
|
|
}
|
2021-10-29 13:19:42 +08:00
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
|
PlainText += (char) (plainMatrix[i][0] + 65);
|
|
|
|
|
}
|
|
|
|
|
System.out.println("Plaintext: " + PlainText);
|
2021-10-06 14:47:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-29 13:19:42 +08:00
|
|
|
|
// Determinant calculator
|
|
|
|
|
public static int determinant(int a[][], int n) {
|
|
|
|
|
int det = 0, sign = 1, p = 0, q = 0;
|
2021-10-06 14:47:44 +08:00
|
|
|
|
|
2021-10-29 13:19:42 +08:00
|
|
|
|
if (n == 1) {
|
|
|
|
|
det = a[0][0];
|
|
|
|
|
} else {
|
|
|
|
|
int b[][] = new int[n - 1][n - 1];
|
|
|
|
|
for (int x = 0; x < n; x++) {
|
|
|
|
|
p = 0;
|
|
|
|
|
q = 0;
|
|
|
|
|
for (int i = 1; i < n; i++) {
|
|
|
|
|
for (int j = 0; j < n; j++) {
|
|
|
|
|
if (j != x) {
|
|
|
|
|
b[p][q++] = a[i][j];
|
|
|
|
|
if (q % (n - 1) == 0) {
|
|
|
|
|
p++;
|
|
|
|
|
q = 0;
|
|
|
|
|
}
|
2021-10-06 14:47:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-10-29 13:19:42 +08:00
|
|
|
|
det = det + a[0][x] * determinant(b, n - 1) * sign;
|
|
|
|
|
sign = -sign;
|
2021-10-06 14:47:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-10-29 13:19:42 +08:00
|
|
|
|
return det;
|
2021-10-06 14:47:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-29 13:19:42 +08:00
|
|
|
|
// Function to implement Hill Cipher
|
|
|
|
|
static void hillcipher(String message) {
|
|
|
|
|
message.toUpperCase();
|
|
|
|
|
System.out.println("What do you want to process from the message?");
|
|
|
|
|
System.out.println("Press 1: To Encrypt");
|
|
|
|
|
System.out.println("Press 2: To Decrypt");
|
|
|
|
|
short sc = in.nextShort();
|
|
|
|
|
if (sc == 1)
|
|
|
|
|
encrypt(message);
|
|
|
|
|
else if (sc == 2)
|
|
|
|
|
decrypt(message);
|
|
|
|
|
else
|
|
|
|
|
System.out.println("Invalid input, program terminated.");
|
|
|
|
|
}
|
2021-10-06 14:47:44 +08:00
|
|
|
|
|
2021-10-29 13:19:42 +08:00
|
|
|
|
// Driver code
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
// Get the message to be encrypted
|
|
|
|
|
System.out.println("Enter message");
|
|
|
|
|
String message = in.nextLine();
|
|
|
|
|
hillcipher(message);
|
2021-10-06 14:47:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|