关于《密码学》第一章习题1.2的java算法实现

求求各位大大给个点赞吧

第一步:我们已知前两个明文和密文我们先计算加密算法和解密算法里面的m和n的值(以便于后续对于加密和解密的实现)

package a3_7.Test.Test2;

import java.util.Scanner;

//计算表达式
//已知密文和明文前两个字符,密文:ed  明文:if
//根据加密算法:E= m * 明文 + n (mod26)   eg:m,n为未知量需要求
//由于知道两组明文和密码可以建立一个二元一次方程组进行a和b求解
//4 = m * 8 + n (mod26)
//3 = m * 5 + n (mod26)

public class Evaluate_expression {
    public char a,b,c,d;


    public int[] Evaluate(){//返回a的值
        Scanner sc=new Scanner(System.in);

        CycleDetection play=new CycleDetection();
        System.out.println("请输入第一个密文");
        a=sc.next().charAt(0);
        a=play.cycledetection(a);


        System.out.println("请输入第二个密文");
        b=sc.next().charAt(0);
        b=play.cycledetection(b);

        System.out.println("请输入第一个明文");
        c=sc.next().charAt(0);
        c=play.cycledetection(c);

        System.out.println("请输入第二个明文");
        d=sc.next().charAt(0);
        d=play.cycledetection(d);

        int[] m=new int[2];
        for(int i=0;i<1000000000;i++){
            for(int j=0;j<i;j++){
                int x1=(int)(a-'a');

                int y1=(int)((c-'a')*i+j);
                int x2=(int)(b-'a');
                int y2=(int)((d-'a')*i+j);

                if((y1%26==x1)&&(y2%26==x2)){
                    m[0]=i;
                    m[1]=j;
                    System.out.println("系数分别是: "+m[0]+" "+m[1]);
                    return m;
                }
            }
        }
        System.out.println("系数分别是: "+m[0]+" "+m[1]);
        return m;
    }




}

第二步:根据第一步得到的m和n实现解密算法

package a3_7.Test.Test2;

import java.util.Scanner;

public class Decryption {
    public char[] Ciphertext;//密文的英文同明文的英文
    Evaluate_expression a=new Evaluate_expression();
    CycleDetection b=new CycleDetection();

    int m[]=a.Evaluate();
    //求逆
    public int Seekinversion(){//求逆
        //求逆运算---> 11 * x = 1 (mod26)
        Scanner sc=new Scanner(System.in);
        //m数组里面的值代表表达是中的a和b;m[0]代表a,m[1]代表b
        int n=m[0];
        int x=0;
        for(int i=0;i<1000000000;i++){
            if((i*n-1)%26==0){//求逆这里应该是-1!!!!!
                x=i;
                break;
            }
        }
        return x;
    }

    //解密
    public void DecryptionTest(){//m是密文
        Scanner sc=new Scanner(System.in);

        System.out.println("请输入你要破解的密钥");
        String ciphertext=sc.next();
        //知识点1:
        //public boolean matches(String regex); //检测字符串是否匹配给定的正则表达式
        String regex="[a-z]+";//正则表达式表示一个或者多个连续的小写字母
        boolean tmp1=ciphertext.matches(regex);
        if(tmp1){

        }else{
            tmp1=true;
            while(tmp1){
                System.out.println("密钥是全英文小写字母的哦    o(´^`)o   ");
                System.out.println("请再次输入要破解的密钥");
                ciphertext=sc.next();
                tmp1=ciphertext.matches(regex);
                if(tmp1==true){
                    tmp1=false;
                }

            }
        }


        Ciphertext=ciphertext.toCharArray();//String类型转换成char数组

        int a=Seekinversion();//逆
        System.out.println("破解完成:");
        for(int i=0;i<Ciphertext.length;i++){

            if(Ciphertext[i]!=' '){
                char tmp='0';
                tmp= (char) ((a*((Ciphertext[i]-'a')-m[1]+26)));
                tmp%=26;
                tmp+='a';
                System.out.print(tmp);
            }else {
                System.out.print(" ");
            }

        }

    }


}

第三步:创建一个测试类进行测试

package a3_7.Test.Test2;

public class test2 {
    public static void main(String[] args) {
        Decryption a=new Decryption();
        a.DecryptionTest();
    }
}

第四步:由于我做这道题的时候,看了一段视频是关于游戏玩家总是输入错误的答案,作者对于这种情况设计的小玩意,所以心血来潮也想设一个,故下列代码出现了

package a3_7.Test.Test2;

import java.util.Scanner;

//循环判断
//主要目的确保输入前两个密文和明文符合要求从而使得程序正常进行
//添加了一些趣味元素
public class CycleDetection {
    Scanner sc=new Scanner(System.in);
    public char cycledetection(char a){
        int count=0;//计数
        while(a<'a'||a>'z'){
            System.out.println("输入错误,请输入小写英文字母");
            a=sc.next().charAt(0);
            count++;
            if(count==3){
                System.out.println("都提醒逆三次了,还耍呢,事不过三!! ಥ_ಥ  ");
                System.out.println("这是最后一次了!!!");
                a=sc.next().charAt(0);
                if (a<'a'||a>'z'){
                    System.out.println("不伺候你了  ඡ·̯ඡ  ");
                    System.exit(0);
                }
            }

        }
        return a;
    }



}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值