这两天开始学了信息安全的密码学的一点知识,开始接触的就是仿射密码,vigenere和Hill密码,虽然这三个密码早已经被淘汰了,但是还是想自己写着试试,用Java写出来了,代码挺简单的,大家可以看看
仿射密码:
package vigenere;
import java.util.Scanner;
public class fangshe {
private static final int number = 26;
/*
* 本代码是仿射密码的加密与解密的实现,内含用欧几里得扩展算法求一个数对于26的逆,
* encrypt函数实现加密,deciphering函数实现解密, Euclid函数实现用欧几里得算法求一个数对于26 的逆
*/
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
System.out.println("please input the message(please input the lowercase)");
String s = input.nextLine();// 输入明文,要求用小写字母,不要打空格
System.out.println("please input the a");
int a = input.nextInt();// 输入放射密码里面的a
System.out.println("please input the b");
int b = input.nextInt();// 输入放射密码里面的b
String ch2 = encrypt(s, a, b);// 调用加密函数,得到密文
System.out.println(ch2);
// deciphering
int a2 = Euclid(a, number);// 采用欧几里得算法计算a的逆。定义为a2;
System.out.println("a2=" + a2);
String ch3 = deciphering(ch2, a2, b);// 调用解密算法,得到明文
System.out.println("ch3=" + ch3);
}
public static String encrypt(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] * a + b) % 26;// 加密算法
}
for (int i = 0; i < ch.length; i++) {
ch[i] = (char) (in[i] + 97);// 将数字变成字母
}
return String.valueOf(ch);// 将字符串数字变成String类型的字符串,返回
}
public static int Euclid(int a, int munber) {// 求a 的逆的实现
int a1 = 1, a2 = 0, a3 = number;
int b1 = 0, b2 = 1, b3 = a;
int t1, t2, t3;
int q;
q = a3 / b3;
System.out.println("q=" + q);
t1 = a1 - q * b1;
t2 = a2 - q * b2;
t3 = a3 - q * b3;
while (t3 != 1) {
a1 = b1;
a2 = b2;
a3 = b3;
b1 = t1;
b2 = t2;
b3 = t3;
q = a3 / b3;
t1 = a1 - q * b1;
t2 = a2 - q * b2;
t3 = a3 - q * b3;
}
int a4 = t2 % munber;
if (a4 < 0)
a4 += munber;// 如果a4小于0,要加上26变正
return a4;// 返回a的逆
}
public static 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类型的字符串,返回
}
}
vigenere密码
package vigenere;
import java.util.Scanner;
public class vigenere {
/*
* 本代码是vigenere密码的加密与解密的实现
* encrypt函数实现加密,deciphering函数实现解密
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
@SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
System.out.println("please input the message(please input the lowercase)");
String s = input.nextLine();// 输入明文,要求用小写字母,不要打空格
System.out.println("please input the Encryptionkey.");
String s2 = input.nextLine();// 输入秘钥,要求用小写字母,不要打空格
String s3 = encrypt(s, s2);//使用加密算法,得到密文
System.out.println(s3);
String s4=deciphering(s3,s2);//使用解密算法,实现解密
System.out.println(s4);
}
public static String encrypt(String s1, String s2) {
char[] ch1 = s1.toCharArray();
int length = ch1.length;// 明文长度
int[] in1 = new int[length];
for (int i = 0; i < ch1.length; i++) {
in1[i] = ch1[i] - 97;// 利用ascii变成0-25数字
}
char[] ch2 = s2.toCharArray();
int length2 = ch2.length;// 明文长度
int[] in2 = new int[length2];
for (int i = 0; i < ch2.length; i++) {
in2[i] = ch2[i] - 97;// 利用ascii变成0-25数字
}
int j = 0;
for (int i = 0; i < length; i++) {
if (j == length2)
j = 0;
in1[i] = (in1[i] + in2[j]) % 26;//加密算法,mod26
j++;
}
for (int i = 0; i < length; i++) {
ch1[i] = (char) (in1[i] + 97);// 将数字变成字母
}
return String.valueOf(ch1);// 将字符串数字变成String类型的字符串,返回
}
public static String deciphering(String s1, String s2) {
char[] ch1 = s1.toCharArray();
int length = ch1.length;// 密文长度
int[] in1 = new int[length];
for (int i = 0; i < ch1.length; i++) {
in1[i] = ch1[i] - 97;// 利用ascii变成0-25数字
}
char[] ch2 = s2.toCharArray();
int length2 = ch2.length;// 明文长度
int[] in2 = new int[length2];
for (int i = 0; i < ch2.length; i++) {
in2[i] = ch2[i] - 97;// 利用ascii变成0-25数字
}
int j = 0;
for (int i = 0; i < length; i++) {
if (j == length2)
j = 0;
in1[i] = (in1[i] - in2[j]) % 26;//解密算法,mod26
if (in1[i] < 0)
in1[i] += 26;//如果得到负数,则加上26转正
j++;
}
for (int i = 0; i < length; i++) {
ch1[i] = (char) (in1[i] + 97);// 将数字变成字母
}
return String.valueOf(ch1);// 将字符串数字变成String类型的字符串,返回
}
}
Hill密码:
package vigenere;
import java.util.Scanner;
public class hill {
private static final int number = 2;
/*
* 本代码是Hill密码的加密与解密的实现 由于加密和解密算法一样,encrypt函数实现加密和解密算法
* 由于笔者笨拙,暂时做的是固定的矩阵长度为2*2的
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
@SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
System.out.println(
"please input the message(please input the lowercase and the length of maessage is the multiple of the 2 )");
String s = input.nextLine();// 输入明文,要求用小写字母,且长度是2 的倍数,不要打空格
System.out.println("please input the Encryptionkey matrix");// 矩阵的输入,2*2矩阵
int[][] in = new int[2][2];
int[][] in2 = new int[2][2];
in[0][0] = input.nextInt();
in[0][1] = input.nextInt();
in[1][0] = input.nextInt();
in[1][1] = input.nextInt();
String s1 = encrypt(s, in);// 加密实现
System.out.println(s1);
// 变换矩阵的逆
in2[0][0] = in[1][1];
in2[0][1] = -in[0][1];
in2[1][0] = -in[1][0];
in2[1][1] = in[0][0];
String s2 = encrypt(s1, in2);// 解密实现
System.out.println(s2);
}
public static String encrypt(String s, int[][] a) {// 加密算法和解密算法是一样的
char[] ch = s.toCharArray();
int length = ch.length;// 明文长度
int[] in = new int[length];
int[] in1 = 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 = i + 2) {// 矩阵的计算
in1[i] = (in[i] * a[0][0] + in[i + 1] * a[1][0]) % 26;
in1[i + 1] = (in[i] * a[0][1] + in[i + 1] * a[1][1]) % 26;
if (in1[i] < 0)
in1[i] += 26;
if (in1[i + 1] < 0)
in1[i + 1] += 26;
}
for (int i = 0; i < ch.length; i++) {
ch[i] = (char) (in1[i] + 97);// 将数字变成字母
}
return String.valueOf(ch);// 将字符串数字变成String类型的字符串,返回
}
}