仿射密码(加法密码+乘法密码)

仿射密码技术:

(加法密码+乘法密码)

(可先参见加法密码与乘法密码原理)


C= Ek(m)=(k1 m+k2) mod n , K1,K2∈Zn ,gcd(k1,n)=1
M= Dk(c)=k3(c- k2) mod n(其中k3为k1逆元)
(1)0<k1<n
(2)k1与n互素,即要满足gcd(k1, n)=1,否则不存在模逆元,不能正确解密
所以即满足乘法密码技术的要求,又满足加法密码的要求,如复合函数一般
K1 K2为密钥。当K1=0时,仿射密码即为乘法密码技术,当K1=1时,即为移位替换密码(加法密码)

乘法密码的密码空间大小是φ(n),φ(n)是欧拉函数。
当n为26字母,则与26互素的数是1、3、5、7、9、11、15、17、19、21、23、25,即φ(n)=12 因此乘法密码的密钥空间为12。
注意:K1=1时 加密变换为恒等变换(即无变化)

测试案例如下:

import java.util.ArrayList;
import java.util.Scanner;

public class 仿射密码技术 {

public static int x=0,y=0;
public static ArrayList<Integer> SecretPlace=new ArrayList();
public static int gcd(int a,int b){
return b>0?gcd(b,a%b):a;
}
public static int ex_gcd(int a,int b){
if(b==0)
   {
       x=1;y=0;
       return a;
   }
   int q=ex_gcd(b,a%b);
   int t=x;x=y;y=t-a/b*y;
   return q;
}
public static void CountSecretPlace(int n){
SecretPlace.add(1);
for(int i=2;i<n;i++){
if(gcd(i, n)==1)
SecretPlace.add(i);
}
}
public static void main(String[] args) {
int k1,k2=0;
Scanner scan=new Scanner(System.in);
System.out.println(“第一行输入密码表总数n\n”
+ “第二行输入各明文字符\n”
+ “第三行输入待加密明文”);
int n=scan.nextInt();
char CharArrays[]=new char[n];
CharArrays=scan.next().toCharArray();
scan.nextLine();
String normalStr=scan.nextLine();
CountSecretPlace(n);
System.out.println(“密钥空间如下,您可选择其中一个值作为乘法密钥K1”);
System.out.println(SecretPlace);
k1=scan.nextInt();
while(!SecretPlace.contains(k1)){
System.out.println(“只能选择密钥空间中的密钥值!请重新选择”);
k1=scan.nextInt();
}
System.out.println(“请选择加法密钥K2,0=<k2<n”);
k2=scan.nextInt();
while(k2<0||k2>=n){
System.out.println(“请重新选择加法密钥K2,0=<k2<n”);
k2=scan.nextInt();
}
ex_gcd(k1, n);
int out=(x+n)%n;
System.out.println(“您选择的乘法密钥模逆元为:”+out);
String splitStrs[]=normalStr.split(” “);
ArrayList<Character> templist=new ArrayList<>();
System.out.println(“加密后如下:”);
for (int j = 0; j < splitStrs.length; j++) {
char normalChars[]=splitStrs[j].toCharArray();
for (int p = 0; p < normalChars.length; p++) {
int t=((normalChars[p]-‘a’)*k1+k2)%n;
normalChars[p]=CharArrays[t];//加密
System.out.print(normalChars[p]);
int tt=(t+n-k2)%n;
normalChars[p]=CharArrays[tt*out%n];//解密
templist.add(normalChars[p]);
}
System.out.print(” “);
templist.add(‘ ‘);
}
System.out.println(“\n解密后如下:”);
for(Character o:templist){
System.out.print(o);
}
}
}
运行结果如下:

第一行输入密码表总数n
第二行输入各明文字符
第三行输入待加密明文
26
abcdefghijklmnopqrstuvwxyz
a man liberal in his views
密钥空间如下,您可选择其中一个值作为乘法密钥K1
[1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25]
1
请选择加法密钥K2,0=<k2<n
3
您选择的乘法密钥模逆元为:1
加密后如下:
d pdq olehudo lq klv ylhzv 
解密后如下:
a man liberal in his views 

    原文作者:JumpFly_W
    原文地址: https://blog.csdn.net/only06/article/details/54784147
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞