【一、实验目的】
通过实验熟练掌握仿射密码算法的加密解密过程,加深对古典密码体制的了解,为深入学习密码学奠定基础。
【二、实验原理】
设两个整数α和β,及gcd(α,26)=1,
加密过程:x → αx+β (mod 26)
解密过程:x → α*(x-β) (mod 26) 其中α•α*= 1(mod 26)
这种加密方法的密钥就是一对(α,β),对gcd(α,26)=1中的α有12种可能的选择,对β有26种选择(因为用mod 26来计算,所以仅需要考虑介于0~25之间的α和β,因此密钥值一共有12•26=312种选择。
【三、实验内容】
下列密文是用仿射密码加密的:edsgickxhuklzveqzvkxwkzukcvuh,请解密。
【四、实验源码】
Affine.java
public class Affine {
public String deciphering(String s,int a, int b){// 解密的实现
char[] ch = s.toCharArray();
int length = ch.length;// 密文长度
int[] in = new int[length];
for (int i = 0; i < ch.length; i++) {
in[i] = ch[i] - 97;// 利用ascii变成0-25数字
}
for (int i = 0; i < length; i++) {
in[i] = ((in[i] - b) * a) % 26;// 解密算法
if (in[i] < 0) in[i] += 26;
}
for (int i = 0; i < ch.length; i++) {
ch[i] = (char) (in[i] + 97);// 将数字变成字母
}
return String.valueOf(ch);// 将字符串数字变成String类型的字符串,返回
}
}
Test.java
public class Test {
public static void main(String[] args) {
Arithmetic arithmetic = new Arithmetic();
final int MOD = 26;
int [] gcd = new int[12];
int m = 0;
String out = null;
for(int i=1;i<MOD;i++){
if((arithmetic.euclid(i,MOD))==1) { //求与26互素的数
gcd[m] = (arithmetic.euclid_2(i,MOD)+26)%26; //求这些数mod26的逆,并把它加入gcd数组
m++;
}
}
Scanner input = new Scanner(System.in);
String s = input.nextLine();// 输入密文
Affine affine = new Affine();
int k =1;
for(int i=0;i<12;i++) {
for (int j = 0; j < 26; j++) {
out = affine.deciphering(s, gcd[i], j);
System.out.println("第"+k+"条明文为:"+out);
k++;
}
}
}
}
说明:输入需要解密的密文,设置循环:α可取值为12个,β可取26个值,分别取出α和β的组合,作为实参调用解密函数deciphering,之后按顺序输出每次解密出的明文。
【五、实验截图】
(1)
说明:直接调用上次写的求逆函数,求于26互逆的数即α,并把它们加入gcd[]数组备用。
(2)
说明:输入需要解密的密文,设置循环:α可取值为12个,β可取26个值,分别取出α和β的组合,作为实参调用解密函数deciphering,之后按顺序输出每次解密出的明文。
(3)
说明:解密函数,先将字符逐个转换成数字,然后根据当前传入的α和β的值,将每个字符对应的数字解密:in[i] = ((in[i] - b) * a) % 26;再将解密后的数字转换成相应的字符,最后合成相应的字符串返回。
(4)输出结果
说明:输入需要解密的密文:edsgickxhuklzveqzvkxwkzukcvuh,之后按照不同α和β的组合按顺序输出解密的密文,最后再第115行找到了正确的明文。