古典密码算法 java_古典密码算法的实现

本文介绍了如何使用Java实现古典密码算法中的仿射变换和换位密码。首先,详细展示了仿射变换的加密和解密过程,包括参数要求和欧几里得算法的应用。接着,探讨了换位密码的加密和解密方法,包括矩阵的重新排列。这些实现有助于理解古典密码学的基本原理。
摘要由CSDN通过智能技术生成

1、古典密码可以分为代替密码和置换密码两种,这里实现了代替密码中的仿射变换和置换密码中的换位变换。

2、仿射变换:

加密过程:e(x) = ax + b (mod m)

解密过程:d(e(x)) = a^(-1)*(e(x) - b) mod m

参数要求:a,m互质;a,b互质;m是集合中元素的个数。(例如当前取1~9和a~z中的所有元素作为集合,m为36)

加密实现:

1 importjava.util.Scanner;2

3 public classMain {4 public static voidmain(String []args) {5 int m = 36, thisNum, index = 0; //m是集合中元素的个数(例如当前取1~9和a~z中的所有元素作为集合,m为36)

6 Scanner s = newScanner(System.in);7 //将输入的字符串转化为字符数组

8 char[] buff =s.nextLine().toCharArray();9 //参数a、b手动输入

10 int a =s.nextInt();11 int b =s.nextInt();12 //参数要求:a,m互质;a,b互质

13 while (fun1(m, a) != 1 || fun1(Math.max(a, b), Math.min(a, b)) != 1) {14 System.out.println("参数不符合要求,请重新输入");15 a =s.nextInt();16 b =s.nextInt();17 }18 for (chari : buff) {19 //由字符转换为数字

20 if (i > '9') thisNum = (int)i - 87;21 else thisNum = (int)i - 48;22 //对该数字加密

23 thisNum = (thisNum*a+b)%m;24 //加密后再将数字转换为字符

25 if (thisNum < 10) buff[index++] = (char)(thisNum+48);26 else buff[index++] = (char)(thisNum+87);27 }28 System.out.println(buff);29 s.close();30 }31

32 //欧几里得算法求两个数的最大公因数

33 public static int fun1(int a, intb) {34 return b == 0 ? a : fun1(b, a%b);35 }36 }

解密实现:

1 importjava.util.Scanner;2

3 public classMain {4 public static voidmain(String []args) {5 int m = 36, thisNum, index = 0, k;6 Scanner s = newScanner(System.in);7 char[] buff =s.nextLine().toCharArray();8 int a =s.nextInt();9 int b =s.nextInt();10 while (fun1(m, a) != 1 || fun1(Math.max(a, b), Math.min(a, b)) != 1) {11 System.out.println("参数不符合要求,请重新输入");12 a =s.nextInt();13 b =s.nextInt();14 }15 //k为a模m的逆元

16 k =fun2(a, m);17 for (chari : buff) {18 //将加密后的字符转换为数字

19 if (i > '9') thisNum = (int)i - 87;20 else thisNum = (int)i - 48;21 //解密过程 D(E(x)) = a^(-1)*(E(x)-b) mod m

22 thisNum = ((thisNum-b)*k)%m;23 //如果结果是负数,则转换为正数,原理为 a % b = (a % b + b) % b

24 if(thisNum < 0) thisNum +=m;25 //最后将解密后的数字转换为字符

26 if (thisNum < 10) buff[index++] = (char)(thisNum+48);27 else buff[index++] = (char)(thisNum+87);28 }29 System.out.println(buff);30 }31

32 public static int fun1(int a, intb) {33 return b == 0 ? a : fun1(b, a%b);34 }35

36 //循环求a模m的逆元

37 public static int fun2(int a, intm) {38 for (int i = 0; i < m; i++) {39 if (a*i%m == 1) {40 a =i;41 break;42 }43 }44 returna;45 }46 }

3、换位密码

加密过程:保持明文的所有字符不变,根据一定的规则重新排列明文。

解密过程:加密过程的逆过程。

注解:加密过程和解密过程都是创建索引的过程,即用数组存储哪个位置放哪个字符,最后再通过索引重新组合成密文或明文。

示例:

明文矩阵:

a s d f g

h j k l m

n b v c

密文矩阵:

d a g s f

k h m j l

v n b c

(计算结果中n和b之间有一个空格,但输出时将空格去掉了)

明文:asdfghjklmnbvc

密钥:31524

加密实现:

1 importjava.util.Scanner;2

3 public classMain {4 public static voidmain(String []args) {5 Scanner s = newScanner(System.in);6 char[] mingwen =s.nextLine().toCharArray();7 char[] miyao =s.nextLine().toCharArray();8 StringBuffer miwen = newStringBuffer();9 int[] poi = new int[miyao.length];10 int index = 0, thisRow = 0, realPoi;11

12 //计算出明文矩阵的列数和行数

13 int col =miyao.length;14 int row = (mingwen.length / col) + (mingwen.length % col == 0? 0 : 1); //处理明文矩阵最后一行可能不满的情况15

16 //密钥位置格式化(密钥中的所有字符都大于等于'1'所以最后减1方便后续计算)

17 for (int i = 0; i < poi.length; i++) poi[i] = miyao[i] - 48 - 1;18

19

20 for (int i = 0; i < row * col; i++) {21 //计算出当前位置i的真正字符(例如加密后第0位为2,即字符d),如果该字符在明文中存在,则将其添加到密文中

22 if ((realPoi = poi[index++] + thisRow * col)

24 else miwen.append(' ');25

26 if (index >=col) {27 index = index %col;28 thisRow++;29 }30 }31

32 //密文去空格(解密时密文中的空格需要保留)

33 for (int i = 0; i < miwen.length(); i++) {34 if (miwen.charAt(i) == ' ') miwen.deleteCharAt(i);35 }36

37 //输出加密后的密文

38 System.out.println(miwen);39 }40 }

解密实现:

1 importjava.util.Scanner;2

3 public classMain {4 public static voidmain(String []args) {5 Scanner s = newScanner(System.in);6 char[] miwen =s.nextLine().toCharArray();7 char[] miyao =s.nextLine().toCharArray();8 StringBuffer mingwen = newStringBuffer();9 int []poi = new int[miyao.length];10 int index = 0, thisRow = 0, realPoi;11

12 //获取解密密钥并将密钥的位置格式化(最后减一),即加密的逆过程

13 for (charc : miyao) {14 poi[(int)c - 48 - 1] = index++;15 }16 index = 0;17

18 //密文矩阵的列数和行数

19 int col =miyao.length;20 int row = (miwen.length / col) + (miwen.length % col == 0? 0 : 1);21

22 for (int i = 0; i < row * col; i++) {23 //计算出当前位置i的真正字符并将该字符添加到明文字符串中

24 if ((realPoi = poi[index++] + thisRow * col)

26 if (index >=col) {27 index = index %col;28 thisRow++;29 }30 }31

32 //输出解密后的明文

33 System.out.println(mingwen);34 }35 }

4、希尔密码(Hill密码)- 属于古典密码中的多表代换密码,运用了基本的矩阵论原理

注解:

1)每个字母当作 26 进制数字:a=0, b=1, c=2... 一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果模 26。用作加密的矩阵(即密匙)必须是可逆的,否则就不可能译码。只有矩阵的行列式和 26 互质,才是可逆的。

2)明文和密文的长度必须是给定的矩阵的列数的整数倍。(矩阵相乘的前提)

加密过程:将明文转化为n维向量(字符转数字)与n×n的矩阵相乘,再将得出的结果模 26 后转化为字符。

解密过程:将明文转化为n维向量(字符转数字)与n×n的矩阵相乘,再将得出的结果模 26 后转化为字符。

加密实现:

1 importjava.util.Scanner;2

3 public classMain {4 public static voidmain(String[] args) {5 //三阶可逆矩阵A

6 int[][] A = { { 1, 2, 3 }, { 1, 1, 2 }, { 0, 1, 2} };7

8 Scanner s = newScanner(System.in);9 char[] mingwen =s.nextLine().toCharArray();10 char[] miwen = new char[mingwen.length];11 int row = 3, col = mingwen.length / 3, index = 0;12

13 while (index

27 for (charc : miwen) {28 System.out.print(c);29 }30 }31 }

解密实现:

1 importjava.util.Scanner;2

3 public classMain {4 public static voidmain(String[] args) {5 //A的逆矩阵

6 int[][] A_1 = {{0, 1, -1}, {2, -2, -1}, {-1, 1, 1}};7

8 Scanner s = newScanner(System.in);9 char[] miwen =s.nextLine().toCharArray();10 char[] mingwen = new char[miwen.length];11 int row = 3, col = mingwen.length / 3, index = 0;12

13 while (index

27 for(charc : mingwen) {28 System.out.print(c);29 }30 }31 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值