(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
相关文章推荐
- HDU - 4497 GCD and LCM
- 全能系统监控工具dstat
- JavaScript利用HTML DOM进行文档操作的方法
- Solr集群搭建
- algrothm_基本数据类型和引用类型变量
- 当前工作主机的环境配置
- Error:(16, 26) 错误: 程序包android.annotation不存在
- ios - 图片自动轮播定时器(NSTimer)以及消息循环模式简介
- mysql:通用查询日志general_log
- iOS之 block,代替代理作为回调函数
- codeigniter -搭配 mssql :问题1 :执行存储过程
- 隐藏导航练习
- sql server2008R2 密钥
- sql server2008安装时提示重启计算机失败怎么办R
- 查看端口是否被占用
- hdfs文件的操作常用命令
- Dialect does not support identity key generation
- Linux――JDK的部署
- 路径转换
- JQuery选择器中层级关系老是记不清楚怎么办,总结下看看。