代换密码(Substitution Cipher)
转载请著明出处
定义
令P=C=Z26,K是由26个数字0,1,…25的所有可能的置换组成,对任意的π∈K,定义eπ(x)=π(x)和dπ(y)=π-1(y),这里的π-1表示置换π的逆置换。
与上一节移位密码相比,移位密码的加密和解密都是代数运算,但是在代换密码的情形下,可简单将加密和解密过程直接看做是一个字母表上的置换。
因为代换密码比较简单,将不做过多的介绍,需要注意的是代换密码的秘钥空间大小是26!>4.0×1026是一个很大的数,因此采用暴力攻击方式即使在计算机上也是不可能的,但是并不是说代换密码不可被破解,使用其他的密码分析方法,代还密码还是可以被攻破。
举个栗子
试用代换密码加密下列明文:
we will meet at midnight,
其中π在Z26上的置换如下
x | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
π(x) | 23 | 13 | 24 | 0 | 7 | 15 | 14 | 6 | 25 | 16 | 22 | 1 | 19 | 18 | 5 | 11 | 17 | 2 | 21 | 12 | 20 | 4 | 10 | 9 | 3 | 8 |
先从如下字母表中获得每个字母对应的数字
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
可得到:
22 4 22 8 11 11 12 4 4 19 0 19 12 8 3 13 8 6 7 19
从置换中可得密文数为:
10 7 10 25 1 1 12 7 7 12 23 12 19 28 0 18 28 14 6 12
从字母表中检索可得密文为:
KHKZ BBTH HMXM TZAS ZOGM
代码实现
package com.slp.cryptography;
import java.util.Arrays;
/**
* @ClassName SubstitutionCipher
* @Description 代换密码
* @Author sanglp
* @Date 2020/11/30 11:24
* @Version 1.0
**/
public class SubstitutionCipher {
static int[] arr = {
23,13,24,0,7,15,14,6,25,16,22,1,19,18,5,11,17,2,21,12,20,4,10,9,3,8};
static int[] arr2 = new int[26];
public static void main(String[] args) {
init();
enCrypt("wewillmeetatmidnight");
deCrypt("KHKZBBTHHMXMTZASZOGM");
}
/**
* 加密 代还密码需要先初始化一个代换表 在此我们用数组来表示
* @param resource
*/
private static void enCrypt(String resource){
char[] chararr = resource.toUpperCase().toCharArray();
StringBuilder result = new StringBuilder();
for(int i=0;i<chararr.length;i++){
result.append( (char) ('A'+arr[chararr[i]-'A']));
}
System.out.println(result);
}
/**
* 解密
* @param resource
*/
private static void deCrypt(String resource){
char[] chararr = resource.toUpperCase().toCharArray();
StringBuilder result = new StringBuilder();
for(int i=0;i<chararr.length;i++){
result.append( (char) ('A'+arr2[chararr[i]-'A']));
}
System.out.println(result);
}
/**
* 初始化逆置换矩阵
*/
private static void init(){
for(int i=0;i<26;i++){
arr2[arr[i]]=i;
}
System.out.println(Arrays.toString(arr2));
}
}