Playfair cypher

Assignment

 After teaching the Playfair cipher and the ADFGVX cipher for several years, Arup was
motivated to make his own cipher. The steps of the cipher are described below:
The plaintext for Arup’s Base 8 cipher must be a sequence of characters with Radix-64
encodings. (If you are not familiar with this encoding system, please Google it.) This allows for all lowercase letters, uppercase letters, digits, the plus sign and the forward slash. The key for the cipher is the 64 possible plaintext characters placed in an 8 x 8 square, where each row and column are labeled 0 through 7, inclusive. Below is a possible key for the cipher. The red colored column is not part of the key and is simply the row labels and the blue colored row is also not part of the key and is simply the column labels. Also, ambiguous symbols in print are labeled with LL standing for lowercase letter, UL standing for uppercase letter and dig standing for digit.

The second key for the cipher is a prime number, p.
We encrypt as follows:
1) Box encryption
We go through each letter in the plaintext of length L, in the following fashion:
for i in [0, L-1]:
a) Find the plaintext letter in the box, the corresponding cipher text is xy, where x and y
are the row and column numbers, respectively of the location of the plaintext character.
b) RotateBox(i)
Here is how the RotateBox function works:
if i is even, we cyclicly rotate row (i%16)/2 to the right by one position
if i is odd, we cyclicly rotate column (i%16)/2 (int division) down by one position.
For example, after one character is encrypted, the new state of the box above is:

After two characters are encrypted the new state of the box is:

When this phase is done, the intermediate ciphertext should be a sequence of 2L digits in base 8
(0 through 7). Let this sequence be d1, d2, …, d2L.
Next, we use the secret key, the prime number, p, to generate a sequence of numbers as follows:
List the 2L + 1 prime numbers after p, in order. Let this sequence be p1, p2, …, p2L+1. Then, create
the sequence s such that si= (pi+1 – pi)/2, for all integers i in [1, 2L].
Then, calculate the 2L base 8 digits of the ciphertextci = (di + si)%8, for all integers i in [1, 2L].
Finally, convert each pair of input (c2i-1, c2i) for all integers i in [1, L] to a single character in
Radix-64. Namely, First convert the pair to base 10 (8c2i-1 + c2i), then convert this to its
corresponding Radix-64 value (‘A’-‘Z’ is 0-25, ‘a’-‘z’ is 26-51, ‘0’-‘9’ is 52-61, ‘+’ is 62 and ‘/’ is 63.)
Your Assignment
In either Python, C, C++ or Java, write a program that carries out encryption using this cipher.
Your program should read in input from standard input and produce output to standard output.
Input Format
The first line of input will have a single positive integer, n, the number of encryptions to carry
out. The first eight lines of each input case will have 8 characters each, representing the 8 x 8
input key. Thus, these lines will contain each of the Radix-64 characters exactly once. The ninth
line of each input case will contain a single positive integer, p (p <105), the second key for the
cipher. The last line of each input case will contain a string in between 1 and 100 Radix-64
characters representing the plaintext.
Output Format
For each input case, output the corresponding plaintext (which should only consist of Radix 64
characters) on a line by itself. 

Solution 

Main.java 

importjava.util.ArrayList;

importjava.util.List;

importjava.util.Scanner;

public class Main {

privateArrayList<String> output=new ArrayList<String>();//this array contains the resulting output for each encoading

privateintnbrEncryption;

private char[][] key=new char[8][8];//the key matrix;

privateint p;//the prime number

String text;

public static ArrayList<Integer> primary=new ArrayList<>();

public static char[] radix64 ={‘A’ , ‘B’ ,

‘C’ , ‘D’ , ‘E’ , ‘F’ , ‘G’ , ‘H’ ,

‘I’ , ‘J’ , ‘K’ , ‘L’ , ‘M’ , ‘N’ ,

‘O’ , ‘P’ , ‘Q’ , ‘R’ , ‘S’ , ‘T’ ,

‘U’ , ‘V’ , ‘W’ , ‘X’ , ‘Y’ , ‘Z’,’a’, ‘b’,

‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’,

‘i’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’,

‘o’, ‘p’, ‘q’, ‘r’, ‘s’, ‘t’,

‘u’, ‘v’, ‘w’, ‘x’, ‘y’, ‘z’,’0′, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’,

‘6’, ‘7’, ‘8’, ‘9’,’+’,’/’};

public static void main(String[] args) {

Main m=new Main();

m.init();

}

private void init(){

try

{

this.primary=sieveOfEratosthenes(21474899);

Scanner scanner=new Scanner(System.in);

nbrEncryption=scanner.nextInt();//number of encryptions

for (int k=0;k<nbrEncryption;k++){

for (int i=0;i<8;i++){

//scanner.close();

scanner=new Scanner(System.in);

String temp=scanner.nextLine();

for (int j=0;j<8;j++){

key[i][j]=temp.charAt(j);

}

}

//scanner.close();

scanner=new Scanner(System.in);

p=scanner.nextInt();

//scanner.close();

scanner=new Scanner(System.in);

text=scanner.nextLine();

addOutput();

}

System.out.println(“OUTPUT :”);

for (String s:output) {

System.out.println(s);

}

}catch (Exception e){

e.printStackTrace();

}

}

private void addOutput() {

ArrayList<Integer> result=boxEncryption();//the list of Di’s

int index=primary.indexOf(p);

List<Integer>  primaries=  primary.subList(index +1 , index +1+(2*text.length() +1));

ArrayList<Integer> primes=new ArrayList<>();

primes.addAll(primaries);

for (int i=0;i<primes.size()-1;i++){

primes.set(i,(primes.get(i+1)-primes.get(i))/2);

}

primes.remove(primes.size()-1);//deleting the last element cuz it’s not part of the new list

for (int i=0;i<result.size();i++){

result.set(i,(result.get(i) + primes.get(i)) % 8);

}

String str=””;

for (int i=0;i<result.size()-2;i+=2){

str+=radix64[(result.get(i)*8) + result.get(i+1)];

}

this.output.add(str);

}

privateArrayList<Integer>boxEncryption() {//this function returns the list of Di

ArrayList<Integer> pairs=new ArrayList<>();

for (int i=0;i<this.text.length();i++){

char c=text.charAt(i);

searchCoordinates(c,pairs);

if ((i%2)==0){

rotateRaw((i % 16)/2);

}else {

rotateColumn((int)(i % 16)/2);

}

}

return pairs;

}

private void rotateColumn(int i) {

char c=key[7][i];

for (int k=7;k>0;k–) key[k][i]=key[k-1][i];

key[0][i]=c;

}

private void rotateRaw(int i) {

char c=key[i][7];

for (int k=7;k>0;k–) key[i][k]=key[i][k-1];

key[i][0]=c;

}

private void searchCoordinates(char letter,ArrayList<Integer>ar) {//this function searches for the char and updates the arraylist

int i=0;

int j=0;

boolean found=false;

while (!found && i<8){

j=0;

while (!found && j<8){

if (letter==key[i][j]) {

ar.add(i);

ar.add(j);

found=true;

}

j++;

}

i++;

}

}

staticArrayList<Integer>sieveOfEratosthenes(int n)

{

// Create a boolean array “prime[0..n]” and initialize

// all entries it as true. A value in prime[i] will

// finally be false if i is Not a prime, else true.

boolean prime[] = new boolean[n+1];

for(int i=0;i<n;i++)

prime[i] = true;

for(int p = 2; p*p <=n; p++)

{

// If prime[p] is not changed, then it is a prime

if(prime[p] == true)

{

// Update all multiples of p

for(int i = p*2; i <= n; i += p)

prime[i] = false;

}

}

ArrayList<Integer> primes=new ArrayList<Integer>();

for(int i = 2; i <= n; i++)

{

if(prime[i] == true)

primes.add(i);

}

return primes;

}

}