Implementation of matrix transformation encryption in java

Posted by nmcglennon on Tue, 23 Jul 2019 13:35:01 +0200

A Playfair cryptographic variant encryption method is as follows: first, a key word (called pair) is selected (letters are not repeated and all are lowercase letters), and then, together with other letters in the alphabet, it is filled into a 5x5 square matrix. The method is as follows:
1. First fill in the key string by row.
2. Immediately thereafter, fill in the letters that are not in the key string in alphabetical order.
3. Since there are only 25 positions in the matrix, the last remaining letter does not need to be changed.
If the key is youandme, the matrix is as follows:
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
When encrypting a pair of letters, such as am, a rectangle with the two letters as vertices is found in the matrix:
o u a
m e b

The encrypted letters of the two letters are another pair of vertices of the rectangle, such as ob in this case.
Please design a program to use the above method to encrypt the input string and output the encrypted string.
There are also the following provisions:
1. A pair of letters, if there is only one letter left at the end, will not be transformed and put directly into the encrypted string;
2. If two letters in a pair of letters are identical, they are not transformed and put directly into the encrypted string.
3. If one of the letters in a pair of letters is not in the square, it does not transform and is put directly into the encrypted string.
4. If a pair of letters appears in the same row or column in a square matrix, such as df or hi, then only two letters need to be simply paired, that is, fd or ih;
5. If a rectangle with a pair of letters as its vertex can be found in the square, if the pair of letters is am, then the letters with a in the other pair of vertex letters of the rectangle should be in front, in the example, ob; similarly, if the pair of letters to be transformed is ta, the transformed letters correspond to wo;
6. The input strings in this program are all lowercase letters and do not contain punctuation, spaces or other characters.
The decryption method is the same as encryption, that is, to encrypt the encrypted string, the original string will be obtained.
Requirements for input are as follows:
Input two lines of string from the console, the first action key word (length less than 25), the second action to be encrypted string (length less than 50), the end of the two lines of string has a carriage return newline character, and both lines of string are lowercase letters, without other characters.
Output encrypted strings on standard output.
For example, if input:
youandme
welcometohangzhou
The input key word is youandme, and the square is as shown above; the string to be encrypted is welcometohangzhou. In the square, we can find a rectangle with the first letter we as the vertex, corresponding to another vertex letter vb, so encrypted as vb, we can also find the vertex letter pairs corresponding to the letters lc,et,oh,ho. The letter pair om is located in the same column of the above square, so it is encrypted directly by inverting the two letters, that is, mo, and the letter pair an is the same. The letter pair z in gz is not in the above square, so it is placed in the encrypted string as it is. The last letter u is output as it is.
So the output is:
vbrmmomvugnagzguu

package com.liu.ex7;

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static char[][] value = new char[5][5];
    public static boolean[] used = new boolean[26];
    
    public int[] getPosition(char s) {
        int[] position = new int[2];
        for(int i = 0;i < 5;i++) {
            for(int j = 0;j < 5;j++) {
                if(value[i][j] == s) {
                    position[0] = i;
                    position[1] = j;
                    return position;
                }
            }
        }
        return position;
    }
    
    public void getResult(String pair, String psw) {
        for(int i = 0;i < 26;i++)
            used[i] = false;
        ArrayList<Character> list = new ArrayList<Character>();
        for(int i = 0;i < pair.length();i++) {
            list.add(pair.charAt(i));
            int temp = pair.charAt(i) - 'a';
            used[temp] = true;
        }
        while(list.size() < 25) {
            for(int i = 0;i < 26;i++) {
                if(used[i] == false) {
                    char temp = (char) ('a' + i);
                    list.add(temp);
                    used[i] = true;
                }
                if(list.size() == 25)
                    break;
            }
        }
        char unUsed = 'a';
        for(int i = 0;i < 26;i++) {
            if(used[i] == false) {
                unUsed = (char) (unUsed + i);
                break;
            }
        }
        int count = 0;
        for(int i = 0;i < 5;i++)
            for(int j = 0;j < 5;j++)
                value[i][j] = list.get(count++);
        
        int len = psw.length();
        ArrayList<Character> result = new ArrayList<Character>();
        if(len % 2 == 1)
            len = len - 1;
        for(int i = 0;i < len;i = i + 2) {
            char temp1 = psw.charAt(i);
            char temp2 = psw.charAt(i + 1);
            int[] position1 = getPosition(temp1);
            int[] position2 = getPosition(temp2);
            if(temp1 == temp2) {
                result.add(temp1);
                result.add(temp2);
            } else if(temp1 == unUsed || temp2 == unUsed) {
                result.add(temp1);
                result.add(temp2);
            } else if(position1[0] == position2[0] || position1[1] == position2[1]) {
                result.add(temp2);
                result.add(temp1);
            } else {
                temp1 = value[position1[0]][position2[1]];
                temp2 = value[position2[0]][position1[1]];
                result.add(temp1);
                result.add(temp2);
            }
        }
        if(psw.length() % 2 == 1)
            result.add(psw.charAt(psw.length() - 1));
        for(int i = 0;i < result.size();i++)
            System.out.print(result.get(i));
        return;
    }
    
    public static void main(String[] args) {
        Main test = new Main();
        Scanner in = new Scanner(System.in);
        String pair = in.next();
        String psw = in.next();
        test.getResult(pair, psw);
    }
}

Topics: less Java