前言:代码说明
该代码由client,server,playfair三个类组成,client发送信息到server,playfair是加密算法的主要实现,含有main函数,可以独立演示加密算法,也可以配合client和server的代码共同实现GUI的界面
1⃣️playfair.java的实现
package 实验1.古典密码1;
import java.io.Serializable;
import java.util.ArrayList;
public class Playfair implements Serializable {
private ArrayList<Character> ciphertext;
private StringBuilder plaintext;//明文
private StringBuilder key;//密钥
private StringBuilder default_char = new StringBuilder("x");
private StringBuilder odd_char = new StringBuilder("f");
private char[] bet;
private char[] matrix;
private char[][] row_col;
private boolean isOdd=false;
class locate {
int i;
int j;
public static final int exception = -1;
private locate(int i, int j) {
this.i = i;
this.j = j;
}
public locate(char[][] a, char tar) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
if (a[i][j] == tar) {
this.i = i;
this.j = j;
return;
}
}
}
this.i = exception;
this.j = exception;
}
public int getI() {
return i;
}
public int getJ() {
return j;
}
}
/**
*
* @param plaintext "playfair cipher was actually"
* @param key "fivestarts"
*/
public Playfair(String plaintext,String key){
this.plaintext = new StringBuilder(plaintext);
this.key = new StringBuilder(key);
this.bet = new char[26];
this.matrix = new char[25];
init();
}
private void addAToZ() {
int count = 26;
for (int i = 0; i < count; i++) {
bet[i] = (char) ('a' + i);
}
}
private void init() {
addAToZ();//初始化字母表,init bet
matrix = initMatrix();
row_col = toMatrix(matrix);
}
/**
* 初始化5X5矩阵
*/
private char[] initMatrix() {
char[] copy = new char[25];
plaintext = new StringBuilder(new String(plaintext).replaceAll("\\s+", ""));//移除空格
handleDuplicate(plaintext);//把相邻的重复字符用一个默认字符拉开距离
if (plaintext.length() % 2 != 0) {//处理字符串长度是奇数的情况
handleOdd(plaintext);//未测试
System.out.println();
}
boolean has_i = isExist(key.toString().toCharArray(), 'i');//如果key中有i
int temp_i = 0;
for (int i = 0; i < key.length(); i++) {
if (!isExist(copy, key.charAt(i))) {
copy[i] = key.charAt(i);
temp_i = i;
}
}
for (int i = temp_i + 1, k = 0; i < bet.length - 1; ) {
if (!isExist(copy, bet[k])) {
if (bet[k] == 'j' && !has_i) {
copy[i++] = bet[k++];
} else if (bet[k] != 'j') {
copy[i++] = bet[k++];
} else {
k++;
}
} else {
++k;
}
}
return copy;
}
private void handleOdd(StringBuilder s) {
s.insert(s.length(), odd_char);
isOdd=true;
}//如果是奇数,在字符串末尾添加默认的奇数字符
private void handleDuplicate(StringBuilder s) {
for (int i = 0; i < s.length(); i += 2) {
if (/*i<s.length()&&*/i + 1 < s.length() && s.charAt(i) == s.charAt(i + 1)) {
s.insert(i + 1, default_char);//添加默认字符x
}
}
}
private char[][] toMatrix(char[] a) {
char[][] b = new char[5][5];
final int col = 5, row = 5;
int k = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
b[i][j] = a[k++];
}
}
return b;
}
private boolean isExist(char[] c, Character target) {
for (int i = 0; i < c.length; i++) {
if (c[i] == target) {
return true;
}
}
return false;
}
public void printMatrix(char[] matrix) {
int count = 5;
for (int i = 0; i < matrix.length; i++) {
System.out.printf("%3c", matrix[i]);
count--;
if (count == 0) {
count = 5;
System.out.println();
}
}
}
public void printMatrix(char[][] m) {
for (var item : m) {
for (var item1 : item) {
System.out.printf("%3c", item1);
}
System.out.println();
}
}
public void printMatrix(ArrayList<Character> a){
int count=5;
for (int i = 0; i < a.size(); i++) {
System.out.printf("%3c",a.get(i));
count--;
if (count==0){
count=5;
System.out.println();
}
}
}
public void printArray(char[] c){
for (var item : c)
{
System.out.printf("%c",item);
}
System.out.println();
}
public void printArray(ArrayList<Character> a){
for (var item : a)
{
System.out.printf("%c",item);
}
System.out.println();
}
static int a = 1;
/**
*
* @param plaintext "playfair cipher was actually"
* @param key "fivestarts"
*/
public static void main(String[] args) {
Playfair p1= new Playfair("playfair cipher was actually","fivestarts");
p1.code();
p1.decode();
}
private ArrayList<Character> generateCode(char[] a) {
ArrayList<Character> res = new ArrayList<>();
for (int i = 0; i + 1 < a.length; i += 2) {
char c1 = a[i];
char c2 = a[i + 1];
char ch1 = '\0', ch2 = '\0';
locate l1 = new locate(row_col, c1);
locate l2 = new locate(row_col, c2);
if (l1.getI() == locate.exception || l2.getI() == locate.exception) {
System.err.println("ERROR LOCATION!!");
System.exit(0);
}
if (l1.getI() != l2.getI() && l1.getJ() != l2.getJ()) {
ch1 = row_col[l1.getI()][l2.getJ()];
ch2 = row_col[l2.getI()][l1.getJ()];
}
else if (l1.getJ() == l2.getJ()) {
ch1 = row_col[(l1.getI() + 1) % 5][l1.getJ()];
ch2 = row_col[(l2.getI() + 1) % 5][l2.getJ()];
}
else if (l1.getI() == l2.getI()) {
ch1 = row_col[l1.getI()][(l1.getJ() + 1) % 5];
ch2 = row_col[l2.getI()][(l2.getJ() + 1) % 5];
}
res.add(ch1);
res.add(ch2);
}
return res;
}
public void code() {
ciphertext=generateCode(plaintext.toString().toCharArray());
printArray(ciphertext);
}
private static char[] CharacterToChar(Character[] a){
char[] b=new char[a.length];
int i=0;
for (var item : a)
{
b[i++]=item;
}
return b;
}
/**
* 下面是解密的代码
*
*/
public ArrayList<Character> decode(){
Character[] c=new Character[ciphertext.size()];
ciphertext.toArray(c);//把ciphertext的元素放到数组c中存储
ArrayList<Character> res=getPlainText(CharacterToChar(c));//传入密文,反向加密得到明文
while (res.contains('x')) {
res.remove(new Character('x'));
}
if (isOdd){
res.remove(res.size()-1);
}
System.out.println();
printArray(res);
return res;
}
private ArrayList<Character> getPlainText(char[] a){
ArrayList<Character> res = new ArrayList<>();
for (int i = 0; i + 1 < a.length; i += 2) {
char c1 = a[i];
char c2 = a[i + 1];
char ch1 = '\0', ch2 = '\0';
locate l1 = new locate(row_col, c1);
locate l2 = new locate(row_col, c2);
if (l1.getI() == locate.exception || l2.getI() == locate.exception) {
System.err.println("ERROR LOCATION!!");
System.exit(0);
}
if (l1.getI() != l2.getI() && l1.getJ() != l2.getJ()) {
ch1 = row_col[l1.getI()][l2.getJ()];
ch2 = row_col[l2.getI()][l1.getJ()];
}
/**
* 加密和解密不同之处在于下面的两个else if和else语句
*/
else if (l1.getJ() == l2.getJ()) {
ch1 = row_col[(l1.getI() + 4) % 5][l1.getJ()];
ch2 = row_col[(l2.getI() + 4) % 5][l2.getJ()];
}
else if (l1.getI() == l2.getI()) {
ch1 = row_col[l1.getI()][(l1.getJ() + 4) % 5];
ch2 = row_col[l2.getI()][(l2.getJ() + 4) % 5];
}
res.add(ch1);
res.add(ch2);
}
return res;
}
public ArrayList<Character> getCiphertext() {
return ciphertext;
}
}
2⃣️Client.java的代码
package 实验1.古典密码1;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Client extends JFrame {
private Socket s;
private JButton send;
private JTextField plainText;
private JTextField key;
private JLabel plainLabel;
private JLabel keyLabel;
private JPanel north;
private JPanel center;
private JPanel south;
{
send=new JButton("发送");
plainText=new JTextField(20);
key=new JTextField(10);
plainLabel=new JLabel("明文");
keyLabel=new JLabel("密钥");
north=new JPanel();
center=new JPanel();
south=new JPanel();
north.add(plainLabel);
north.add(plainText);
center.add(keyLabel);
center.add(key);
south.add(send);
add(north,BorderLayout.NORTH);
add(center,BorderLayout.CENTER);
add(south,BorderLayout.SOUTH);
/**
* playfair cipher was actually
* fivestarts
*/
send.addActionListener(e->{
String iplain=plainText.getText();
String ikey=key.getText();
try {
s=new Socket("127.0.0.1",30000);
Playfair p1= new Playfair(iplain,ikey);
p1.code();
ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
oos.writeObject(p1);
oos.flush();
} catch (Exception e1) {
e1.printStackTrace();
}
});
}
public Client(){
super("加密窗口🔐");
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Client();
}
}
3⃣️server.java的代码
package 实验1.古典密码1;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Scanner;
public class Server extends JFrame {
private ServerSocket ss;
private Socket s;
private String key="fivestarts";
private JLabel dir;
private JTextField cnt;
private JButton get;
private JPanel north;
private JLabel cla;
private JTextField jtf2;
private JPanel center;
{
cla=new JLabel("密文");
jtf2=new JTextField(20);
center=new JPanel();
dir=new JLabel("解密内容");
cnt=new JTextField(20);
get=new JButton("一键解密🔓");
north=new JPanel();
north.add(dir);
north.add(cnt);
center.add(cla);
center.add(jtf2);
add(north,BorderLayout.NORTH);
add(center,BorderLayout.CENTER);
add(get,BorderLayout.SOUTH);
get.addActionListener(e->{
try {
ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
Playfair p1=(Playfair)ois.readObject();
ArrayList<Character> ans=p1.decode();
StringBuilder s=new StringBuilder();
for (var item : ans)
{
s.append(item);
}
cnt.setText(s.toString());
StringBuilder sx=new StringBuilder();
ArrayList<Character> a2=p1.getCiphertext();
for (var item : a2)
{
sx.append(item);
}
jtf2.setText(sx.toString());
} catch (Exception e2) {
e2.printStackTrace();
}
});
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
Server(){
super("解密大行动");
try {
ss=new ServerSocket(30000);
s=ss.accept();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Server();
}
}