仿射密码算法(java实现)
仿射密码的加密函数:
e
k
(
x
)
=
a
x
+
b
(
m
o
d
26
)
,
a
,
b
∈
Z
26
e_k(x)=ax+b(mod 26),a,b∈Z_{26}
ek(x)=ax+b(mod26),a,b∈Z26
要求唯一解的充要条件是
g
c
d
(
a
,
26
)
=
1
gcd(a,26)=1
gcd(a,26)=1
gcd是最大公因数的意思
该仿射密码的解密函数为:
d
k
(
y
)
=
a
−
1
(
y
−
b
)
(
m
o
d
26
)
d_k(y)=a^{-1}(y-b)(mod 26)
dk(y)=a−1(y−b)(mod26)
注意:a-1是指在模26下的倒数
原理我就不多介绍了,感兴趣的同学自己动手百度啦。
下面是我用java写的加密解密的工具类:
package com.ibianma;
import java.util.Random;
/**
* 加密解密工具类
*/
public class EncryAndDecry {
private static int a;
private static int b;
/**
* 初始化给a和b赋值
*/
static {
do {
a=(int)(Math.random()*26);
b=(int)(Math.random()*26);
} while (a==0||b==0||gcd(26,a)!=1||gcd(26,b)!=1);
}
/**
* 求最大公因数
* @param a 较大的数
* @param b 较小的数
* @return 最大公因数
*/
public static int gcd(int a,int b){
if (b>a){
int c;
c=a;
a=b;
b=c;
}
return a%b==0?b:gcd(b,a%b);
}
/**
* 模26求倒数函数
* @return 模26下的倒数
*/
public static int reciprocal(){
int q = 1;
for (int i = 3; i <26 ; i=i+2) {
if ((a*i)%26==1){
q=i;
break;
}
}
return q;
}
/**
* 加密算法
* @param mingWen 明文
* @return 密文
*/
public static String encryption(String mingWen){
String s = "";
char[] chars = mingWen.toCharArray();
for (char aChar : chars) {
int i= aChar;
if(i>=65&&i<65+26){
String i1 = (char)( (a*(i-65)+b)%26+65)+"";
s=s+i1;
}
else if (i>=97&&i<97+26){
String i1 = (char) ( (a*(i-97)+b)%26 +97)+"";
s=s+i1;
}else {
continue;
}
}
return s;
}
/**
* 解密算法
* @param miWen 密文
* @return 明文
*/
public static String decrypt(String miWen){
int reciprocal = reciprocal();
String s = "";
char[] chars = miWen.toCharArray();
for (char aChar : chars) {
int i= aChar;
if(i>=65&&i<65+26){
int temp=(i-65)-b;
if (temp<0){
temp=temp+26;
}
String i1 = (char)( (reciprocal*temp)%26+65)+"";
s=s+i1;
}
else if (i>=97&&i<97+26){
int temp=(i-97)-b;
if (temp<0){
temp = temp+26;
}
String i1 = (char) ((reciprocal*temp)%26+97)+"";
s=s+i1;
}else {
continue;
}
}
return s;
}
public static int getA() {
return a;
}
public static int getB() {
return b;
}
}
在主函数里测试了一下:
测试代码如下:
Scanner scanner = new Scanner(System.in);
System.out.print("请输入要加密的明文:");
String s = scanner.next();
String encryption = EncryAndDecry.encryption(s);
System.out.println("加密后的密文为:"+encryption);
String decrypt = EncryAndDecry.decrypt(encryption);
System.out.println("解密后的明文为:"+decrypt);
System.out.println("a:"+EncryAndDecry.getA()+" b:"+EncryAndDecry.getB()+" a逆:"+EncryAndDecry.reciprocal());
测试结果如下:
D:\project\java\jdk\bin\java.exe "-javaagent:D:\project\Idea\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=64507:D:\project\Idea\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\project\java\jdk\jre\lib\charsets.jar;D:\project\java\jdk\jre\lib\deploy.jar;D:\project\java\jdk\jre\lib\ext\access-bridge-64.jar;D:\project\java\jdk\jre\lib\ext\cldrdata.jar;D:\project\java\jdk\jre\lib\ext\dnsns.jar;D:\project\java\jdk\jre\lib\ext\jaccess.jar;D:\project\java\jdk\jre\lib\ext\jfxrt.jar;D:\project\java\jdk\jre\lib\ext\localedata.jar;D:\project\java\jdk\jre\lib\ext\nashorn.jar;D:\project\java\jdk\jre\lib\ext\sunec.jar;D:\project\java\jdk\jre\lib\ext\sunjce_provider.jar;D:\project\java\jdk\jre\lib\ext\sunmscapi.jar;D:\project\java\jdk\jre\lib\ext\sunpkcs11.jar;D:\project\java\jdk\jre\lib\ext\zipfs.jar;D:\project\java\jdk\jre\lib\javaws.jar;D:\project\java\jdk\jre\lib\jce.jar;D:\project\java\jdk\jre\lib\jfr.jar;D:\project\java\jdk\jre\lib\jfxswt.jar;D:\project\java\jdk\jre\lib\jsse.jar;D:\project\java\jdk\jre\lib\management-agent.jar;D:\project\java\jdk\jre\lib\plugin.jar;D:\project\java\jdk\jre\lib\resources.jar;D:\project\java\jdk\jre\lib\rt.jar;D:\spring boot code\coding theory\out\production\coding theory" com.ibianma.CodingTest
请输入要加密的明文:safdsgHJGBJHG
加密后的密文为:tpgutzSEZIESZ
解密后的明文为:safdsgHJGBJHG
a:19 b:15 a逆:11
Process finished with exit code 0