Add Hill Cipher (Hacktoberfest) (#2463)
This commit is contained in:
parent
2440fc70f8
commit
30d9631a64
172
Ciphers/HillCipher.java
Normal file
172
Ciphers/HillCipher.java
Normal file
@ -0,0 +1,172 @@
|
||||
package Ciphers;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
public class HillCipher{
|
||||
static Scanner in = new Scanner (System.in);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
for (i = 0; i < n; i++)
|
||||
CipherText += (char)(cipherMatrix[i][0] + 65);
|
||||
}
|
||||
System.out.println("Ciphertext: "+ CipherText);
|
||||
}
|
||||
//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;
|
||||
}
|
||||
//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++)
|
||||
{
|
||||
plainMatrix[i][0] += keyMatrix[i][x] * messageVector[x][0];
|
||||
}
|
||||
|
||||
plainMatrix[i][0] = plainMatrix[i][0] % 26;
|
||||
}
|
||||
for (i = 0; i < n; i++)
|
||||
PlainText += (char)(plainMatrix[i][0] + 65);
|
||||
}
|
||||
System.out.println("Plaintext: "+PlainText);
|
||||
}
|
||||
|
||||
// Determinant calculator
|
||||
public static int determinant(int a[][], int n){
|
||||
int det = 0, sign = 1, p = 0, q = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
det = det + a[0][x] *determinant(b, n-1) * sign;
|
||||
sign = -sign;
|
||||
}
|
||||
}
|
||||
return det;
|
||||
}
|
||||
|
||||
// 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.");
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user