卡思维的点:
1、应将j视为i
2、解密只得出i没法得出j,因此应根据语义猜密文中的i是i还是j。
3、密文中的z同样需要自己根据语义判断是添加的还是原来就有的。
参考链接:
古典密码:playfair(Java实现)_会飞的咩咩的博客-CSDN博客
从电影《国家宝藏2》中谈Playfair密码算法
信息安全-1:python之playfair密码算法详解[原创] - 前程明亮 - 博客园
上代码:
import java.util.ArrayList;
import java.util.Scanner;
public class test {
public static void main(String[] args) {
String miyao = "playfair"; //密钥
ArrayList mingWen = new ArrayList(); //明文信息
ArrayList miWen;
System.out.println("请输入你要传输的信息:");
Scanner scanner = new Scanner(System.in);
String input = scanner.next();
char[][] miyaoTable = miYaoTable(miyao); //密钥表
char[] inputChar = input.toCharArray();
for (int i = 0; i < inputChar.length; i++){
mingWen.add(inputChar[i]);
}
miWen = jiaMi(miyaoTable,mingWen); //加密得到密文
System.out.println("-----------------------");
System.out.print("密钥为:");
System.out.println(miyao);
System.out.println("密码表为:");
for (int i = 0; i < 5; i++){
for (int j = 0; j < 5; j++){
System.out.print(miyaoTable[i][j]);
}
System.out.println();
}
System.out.println("-----------------------");
System.out.println("密文为:");
miWen.forEach(System.out::print);
System.out.println();
System.out.println("-----------------------");
System.out.println("反解密后得到的明文为:");
ArrayList mingWen2 = jiemi(miyaoTable,miWen);
System.out.println(mingWen2);
}
public static char[][] miYaoTable(String miyao){
char[] keychar = miyao.toCharArray(); //密钥char
char[] dkeychar = new char[keychar.length]; //整理后的密钥
char[] alphabet = new char[25]; //字母表
char[][] miyaoTable = new char[5][5]; //密钥表
//生成字母表 将j视i 因此不加入j
for(int i = 0; i < 26; i++){
if (i < 9){
alphabet[i] = (char)(97 + i);
}
if (i > 9){
alphabet[i - 1] = (char)(97 + i);
}
}
//整理密钥 去重 尾部加z
int count = 0;
int j,i;
int[] temp = new int[25];
for (i = 0; i < keychar.length; i++){
if (keychar[i] == 'j'){keychar[i] = 'i';}//将j用i替换
}
for (i = 0; i < keychar.length; i++){
for (j = 0; j < keychar.length; j++){
if (dkeychar[j] == keychar[i]){
break;
}
}
if (j == keychar.length){
dkeychar[count] = keychar[i];
for (int k = 0; k < alphabet.length; k++){
if (dkeychar[count] == alphabet[k]){
temp[k] = 1;
}
}
count++;
}
}
//编写密钥表
int k = 0;
int m = 0;
int sign = 0;
for (i = 0; i < 5; i++){
for (j = 0; j < 5; j++){
if (dkeychar[k] != 0 && sign == 0){
miyaoTable[i][j] = dkeychar[k];
k++;
if (k == dkeychar.length - 1){sign = 1;}
}else {
for (; m < alphabet.length; ){
if (temp[m] == 0){
miyaoTable[i][j] = alphabet[m];
m++;
break;
}
m++;
}
}
}
}
return miyaoTable;
}
public static ArrayList jiaMi(char[][] miYao, ArrayList mingWen){
ArrayList miWen = new ArrayList<>();
int[][] position;
//整理明文 字母对重复则在中间加z 个数为奇则在最后加z
for (int i = 0; i < mingWen.size(); i++) {
if (i % 2 == 0 & i != mingWen.size() - 1) {
if (mingWen.get(i).equals(mingWen.get(i + 1))) {
mingWen.add(i + 1, 'z');
}
}
}
if (mingWen.size() % 2 != 0){
mingWen.add('z');
}
//根据在密钥表中文字找到对应的替换字母
for (int i = 0; i < mingWen.size(); i++){
if (i % 2 == 0){
position = getPosition(mingWen.get(i),mingWen.get(i + 1),miYao);
int rowA = position[0][0];
int colA = position[0][1];
int rowB = position[1][0];
int colB = position[1][1];
int temp;
if (rowA == rowB){
miWen.add(miYao[rowA][(colA + 1) % 5]);
miWen.add(miYao[rowB][(colB + 1) % 5]);
}else if (colA == colB){
miWen.add(miYao[(rowA + 1) % 5][colA]);
miWen.add(miYao[(rowB + 1) % 5][colB]);
}else {
miWen.add(miYao[rowA][colB]);
miWen.add(miYao[rowB][colA]);
}
}
}
return miWen;
}
public static int[][] getPosition(char n1,char n2,char[][] miyaoTable){
int[][] position = new int[2][2];
if (n1 == 'j'){n1 = 'i';} //将j视为i
if (n2 == 'j'){n2 = 'i';} //将j视为i
for (int i = 0; i < miyaoTable.length; i++){
for (int j = 0; j < miyaoTable.length; j++){
if (n1 == miyaoTable[i][j]){
position[0][0] = i;
position[0][1] = j;
}
if (n2 == miyaoTable[i][j]){
position[1][0] = i;
position[1][1] = j;
}
}
}
return position;
}
public static ArrayList jiemi(char[][] miYaoTable, ArrayList miWen){
ArrayList mingWen = new ArrayList<>();
int[][] position;
for (int i = 0; i < miWen.size(); i = 2 + i){
position = getPosition(miWen.get(i), miWen.get(i + 1), miYaoTable);
int rowA = position[0][0];
int colA = position[0][1];
int rowB = position[1][0];
int colB = position[1][1];
int temp;
if (rowA == rowB){
mingWen.add(miYaoTable[rowA][(colA - 1 + 5) % 5]);
mingWen.add(miYaoTable[rowB][(colB - 1 + 5) % 5]);
}else if (colA == colB){
mingWen.add(miYaoTable[(rowA - 1 + 5) % 5][colA]);
mingWen.add(miYaoTable[(rowB - 1 + 5) % 5][colB]);
}else {
mingWen.add(miYaoTable[rowA][colB]);
mingWen.add(miYaoTable[rowB][colA]);
}
}
return mingWen;
}
}
输出结果:觉得不错麻烦给个赞。



