您的位置:首页 > 其它

(5)复杂置换

2016-03-28 10:44 183 查看




即:加密时把明文一行一行地转换成矩阵(密钥的长度即为矩阵的列数),然后按照密钥(置换表)改变列的次序,按列读取,构成密文;解密时把密文一列一列地转换成矩阵(密钥的长度即为矩阵的列数),然后按照密钥(逆置换表)改变列的次序,按行读取,构成明文。

具体Java实现代码如下:

import java.util.ArrayList;
import java.util.List;

/**
* 一种更复杂的置换方案是把消息一行一行地写成矩形块,
* 然后按列读出,但是把列的次序打乱。列的次序就是算法的密钥。
* @author Angela
*/
public class Display1 {

/**
* 得到逆置换
* @param K 置换表
* @return 逆置换表
*/
public static int[] reverseK(int[] K){
int len=K.length;
int[] key=new int[len];
List<Integer> list=new ArrayList<Integer>();
for(int k: K){
list.add(k);
}
for(int i=0;i<len;i++){
key[i]=list.indexOf(i+1)+1;//List第一个下标是0
}
return key;
}

/**打印密钥**/
public static void printK(int[] K){
for(int i=0;i<K.length;i++)
System.out.print(K[i]+" ");
System.out.println();
}

/**
* 根据密钥将矩阵列的次序打乱
* @param matrix 矩阵
* @param K 密钥
* @return
*/
public static char[][] displayMatrix(char[][] matrix,int[] K){
int rowNum=matrix.length;
int colNum=K.length;
char[][] newMatrix=new char[rowNum][colNum];
for(int i=0;i<rowNum;i++){
for(int j=0;j<colNum;j++){
//行保持不变,列的次序为密钥
int index=K[j]-1;
newMatrix[i][index]=matrix[i][j];//数组第一个下标是0
}
}
return newMatrix;
}

/**打印矩阵**/
public static void printMatrix(char[][] matrix){
for(int i=0;i<matrix.length;i++){
for(int j=0;j<matrix[i].length;j++){
System.out.print(matrix[i][j]+" ");
}
System.out.println();
}
}

/**
* 把明文一行一行转换成矩阵
* @param P 明文
* @param colNum 列数
* @return
*/
public static char[][]  dealP(String P,int colNum){
P=P.replaceAll(" ","").toUpperCase();//去除空格,并转换成大写
int rowNum=P.length()/colNum;
char[][] matrix=new char[rowNum][colNum];
int count=0;
//把消息一行一行地写成矩形块
for(int i=0;i<rowNum;i++){
for(int j=0;j<colNum;j++){
matrix[i][j]=P.charAt(count++);
}
}
return matrix;
}

/**
* 对明文进行加密
* @param P 明文
* @param K 密钥
* @return 密文
*/
public static String encrypt(String P,int[] K){
int colNum=K.length;
char[][] matrix=dealP(P,colNum);
//printMatrix(matrix);
char[][] newMatrix=displayMatrix(matrix,K);
//printMatrix(newMatrix);
int rowNum=newMatrix.length;
StringBuilder sb=new StringBuilder();
//按列读出
for(int i=0;i<colNum;i++){
char[] col=new char[rowNum];
for(int j=0;j<rowNum;j++){
col[j]=newMatrix[j][i];
}
sb.append(col);
}
return sb.toString();
}

/**
* 把密文一列一列转换成矩阵
* @param C 密文
* @param colNum 列数
* @return
*/
public static char[][]  dealC(String C,int colNum){
C=C.replaceAll(" ","").toUpperCase();//去除空格,并转换成大写
int rowNum=C.length()/colNum;
char[][] matrix=new char[rowNum][colNum];
int count=0;
//把密文一列一列地写出矩形块
for(int i=0;i<colNum;i++){
for(int j=0;j<rowNum;j++){
matrix[j][i]=C.charAt(count++);
}
}
return matrix;
}

/**
* 对密文进行解密
* @param C 密文
* @param K 密钥
* @return 明文
*/
public static String decrypt(String C,int[] K){
int colNum=K.length;
char[][] matrix=dealC(C,colNum);
char[][] newMatrix=displayMatrix(matrix,K);
//printMatrix(newMatrix);
int rowNum=newMatrix.length;
StringBuilder sb=new StringBuilder();
//按行读出
for(int i=0;i<rowNum;i++){
char[] col=new char[colNum];
for(int j=0;j<colNum;j++){
col[j]=newMatrix[i][j];
}
sb.append(col);
}
return sb.toString();
}

/**测试**/
public static void main(String args[]){
String P="Attack Postpone Duntilt Woamxyz";
int[] K={4,3,1,2,5,6,7};
String C=encrypt(P,K);
System.out.println("密文:"+C);
int[] rkey=reverseK(K);
System.out.print("逆置换:");
printK(rkey);
System.out.println("明文:"+decrypt(C,rkey));
}

}


结果如下:

密文:TTNAAPTMTSUOAODWCOIXKNLYPETZ

逆置换:3 4 2 1 5 6 7

明文:ATTACKPOSTPONEDUNTILTWOAMXYZ
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: