用Java实现仿射密码,vigenere和Hill密码,内含用欧几里得算法实现一个数对于26的逆

      这两天开始学了信息安全的密码学的一点知识,开始接触的就是仿射密码,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类型的字符串,返回
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值