密码学第一次实验
古典密码的实现
1.密钥字法
首先选择一便于记忆的字母串作为密钥字,然后按如下方法形成明密代替表:
去掉重复字母,依次列出密钥字中各字母,
再依次列出字母表中其余的字母。
特点:便于记忆, 但密钥量|K|比较小。
2.洗牌法
对分别写有26个英文字母的26张纸牌进行若干次洗牌,最后依次取出形成密文字母行,即为洗牌构造方法。
特点:
密钥空间K由26个英文字母的所有可能的全排列构成
密钥量|K|=26!,密钥不容易被猜测,但不便于记忆。
3.仿射法—公式法
X=Y= {0,1,2, … ,q-1} = Zq
c =Ek(m)=(k2m+k1) mod q
且gcd(k2,q)==1
也就是说k2和q必须互素
特点:便于用计算机实现。
代码
1.周期3的置换密码
package PWtest;
import java.util.ArrayList;
import java.util.Scanner;
/*
* 周期置换密码
* */
public class test1_1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String keyWord = "";//密钥字
/*使用的密码主要是字母上的改变,包括置换和移位*/
String message0 = "abcdefghijklmnopqrstuvwxyz";
char[] tempKey;
char[] message0Char = message0.toCharArray();
ArrayList<Character> tempKey1;
System.out.println("输入密钥字:");
keyWord = scanner.next();
System.out.println("密钥字法生成的明密文代替表:");
tempKey1 = new ArrayList<Character>();
tempKey = keyWord.toCharArray();
/*1.密钥字法:
* 输入密钥,检查是否存在重复的情况。如果有,只再第一次出现该字母的位置添加交换。
* 遍历26个字母,将其他的字母位置补齐。
* */
//大循环遍历密钥字
for (int i = 0; i < keyWord.length(); i++) {
//小循环检查前面有没有重复的密钥字
int bug = 0;
for (int j = 0; j < i; j++) {
if (tempKey[i] == tempKey[j]) {
//如果有重复的,表现在bug值
bug = -1;
break;
}
}
//若没有重复,将这个字符加到列表中
if (bug == 0) {
tempKey1.add(tempKey[i]);
}
}
//再来个遍历26个字母的,把密钥序列补齐
for (int i = 0; i < 26; i++) {
int bug = 0;
for (int j = 0; j < tempKey1.size(); j++) {
if (message0Char[i] == tempKey1.get(j)) {
bug = -1;
}
}
if (bug == 0) {
tempKey1.add(message0Char[i]);
}
}
//将List中的密钥转换成char数组,方便使用
char[] code1 = new char[26];
for (int i = 0; i < tempKey1.size(); i++) {
code1[i] = tempKey1.get(i);
}
System.out.println("明 " + message0);
System.out.print("密 ");
for (int i = 0; i < code1.length; i++) {
System.out.print(code1[i]);
}
System.out.println();
/*2.洗牌法
生成随机