古典密码学虽然现在已经不再使用,但其反映了密码设计和破译的基本思想,是学习密码学的入口。
古典密码学主要有两种体制:置换密码和代换密码。
置换密码
根据一定的规则重新排列明文,以便打破原有的结构特性。即改变字符的原始位置,但字符还是那些字符。
- 列置换:比如明文m = “Beijing 2008 Olympic Games”,
密钥=(1 4 3)(5 6)。
该密钥表示:一个括号一个循环,f(1) = 4,f(4) = 3 , f(3) = 1,这里3是括号的末尾,所以f(3)的值就循环到了括号的最前面,即1。(5 6)类似,f(5) = 6 , f(6) = 5。少了2,未表示出来的等于其自身,所以f(2) = 2。其中f(a) = b 表示 a 列和 b 列的数据交换。由于它最大的数是6,则表示分组长度是6,那么将明文m写成如下形式:
B e i j i n
g 2 0 0 8 O
l y m p i c
G a m e s *
‘*’号为填充,经过加密后结果为:
j e B i n i
0 2 g 0 O 8
p y l m c i
e a G m * s
获得密文c=“jeBini02g0O8pylmcieaGm*s”
解密时需要变换密钥,(1 4 3)的逆置换为(1 3 4),变换规则:对于每一个括号,第一个数字不变,后面反转。例:(1 2 3 4 5) -》 (1 5 4 3 2)。是不是很简单。那么上一个解密密钥=(1 3 4)(5 6),容易由密文再根据解密密钥获得明文。
写了代码试了下,仅供参考:
package Classical;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Permutation {
// private static final int MAXCOL = 1024;
public static void main(String[] args) {
// TODO Auto-generated method stub
String c = String.valueOf(columnEncry("Beijing 2008 Olympic Games", "(1 4 3)(5 6)"));
System.out.println("密文:"+c.replace(" ",""));
String m = String.valueOf(columnEncry(c,"(1 3 4)(5 6)"));
System.out.println("明文:"+m.replace(" ",""));
}
/*
*@author 孤舟一叶
*@param in表示要加密的数据,key表示密钥,形如(1 4 3)(5 6)
*@return 返回密文
*/
public static StringBuilder columnEncry(String in, String key){
int colNum = 0;
Map<Integer,Integer> relation = new HashMap<Integer,Integer>();
String[] keySplited = key.split("[(]");
for(int i = 1 ; i < keySplited.length ; i++){
int len = keySplited[i].length()-<