说明:
加法密码和乘法密码结合就构成仿射密码,仿射密码的加密和解密算法是:
C=Ek(m)=(k1m+k2) mod n
;M= Dk(c)=k3(c- k2) mod n
(其中(k3 ×k1)mod26 = 1)
; 仿射密码具有可逆性的条件是:
gcd(k1, n)=1
. 当k1=1
时,仿射密码变为加法密码,当k2=0
时,仿射密码变为乘法密码。仿射密码中的密钥空间的大小为nφ(n)
,当n
为26
字母,φ(n)=12
,因此仿射密码的密钥空间为12×26 = 312
。 加密举例:
设密钥K= (7, 3)
, 用仿射密码加密明文hot
。 三个字母对应的数值是7
、14
和19
。
(7×7 + 3) mod 26 = 52 mod 26 =0(7×14 + 3) mod 26 = 101 mod 26 =23(7×19 + 3) mod 26 =136 mod 26 =6
三个密文数值为0
、23
和6
,对应的密文是AXG
。
解密举例:
先来引入一个定义.
大家知道, 好多东西都有逆, 大家读小学时都知道,两个数相乘乘机为1
,则互为倒数, 其实是最简单的逆. 后来, 我们到了高中, 我们学习了逆函数; 到了大学, 我们学习线性代数,知道两个矩阵的乘积为单位矩阵的话,则这两个矩阵互为逆矩阵. 现在我跟大家介绍另一种逆. 叫模逆. 其实很好理解的, 如下: 若a
,b
两数的乘积对正整数n取模的结果为1. 则称a
,b
互为另外一个的模逆. 比如: 3*7 = 21; 21 % 20 = 1 ; 所以3,7 互为 20 的 模逆. 9*3 = 27; 27 % 26 = 1 ; 所以9,3 互为 26 的 模逆.
如何标记? 若a
,b
互为n
的模逆 , 即b
为a
的模n
的逆元,则记b
为a-1mod n
看了上面的定义, 我们知道:
a
与n
互素的时候,a
才是有模逆的.其他情况下是不存在模逆的, 比如2
对26
就没有模逆. 求模逆的方法:
利用计算机的强大运算能力从2
穷举
另外一种巧妙的方法 ----
java
代码实现:
package com.jiangbiao.firsthomework;import java.util.Scanner;/** * 仿射密码的加密和解密 * n = 26 */public class AffineCipher { //n public static final int n = 26; public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.println("请输入密钥k1:"); int k1 = input.nextInt(); System.out.println("请输入密钥k2:"); int k2 = input.nextInt(); Scanner input2 = new Scanner(System.in); System.out.println("请输入明文:"); String express = input2.nextLine(); //加密 String ciphertext; ciphertext = encryptionOperation(k1, k2, express); System.out.println("密文:" + ciphertext); //解密 String decrypttext = Decrypt(k1, k2, ciphertext); System.out.println("解密结果:" + decrypttext); } /** * 加密:C= Ek(m)=(k1m+k2) mod n * @param k1 * @param k2 * @param express * @return */ public static String encryptionOperation(int k1, int k2, String express){ //转化成小写并去除空格 String express2 = express.toLowerCase().replaceAll(" ", ""); System.out.println("express2:" + express2); char[] expressChar = express2.toCharArray(); int[] jiamiChar = new int[express2.length()]; //将字母转换成数字表示 for (int i=0;i
/** * 示例1: 请输入密钥k1: 7 请输入密钥k2: 3 请输入明文: hot express2:hot 0 23 6 密文:AXG k3:15 解密结果:HOT */ /** * 示例2: 请输入密钥k1: 11 请输入密钥k2: 7 请输入明文: MXJFDEDD express2:mxjfdedd 9 0 2 10 14 25 14 14 密文:JACKOZOO k3:19 解密结果:MXJFDEDD */