中国剩余定理&RSA算法java实现

中国剩余定理java实现

孙子定理是中国古代求解一次同余式组(见同余)的方法。是数论中一个重要定理。又称中国余数定理。一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。《孙子算经》中首次提到了同余方程组问题,以及以上具体问题的解法,因此在中文数学文献中也会将中国剩余定理称为孙子定理。
 

package js;

import java.util.Scanner;

public class Zgsy {
    public static void main(String[] args) {


        Scanner scanner = new Scanner(System.in);

        System.out.println("格式:X = b mod m");
        System.out.println("请输入方程组数目:");
        int l = scanner.nextInt();//方程组数目


        System.out.println("请输入b:");
        int[] b = new int[l];//存b值
        for (int i = 0; i < l; i++) {
            b[i] = scanner.nextInt();
        }


        System.out.println("请输入m:");
        int[] m = new int[l];//存m值
        for (int i = 0; i < l; i++) {
            m[i] = scanner.nextInt();
        }


        //1.求M的值
        int M = 1;
        for (int i = 0; i < l; i++) {
            M *= m[i];
        }

            System.out.println("M = "+M);


        //2.求M / m
        int[] M_m = new int[l];//存M/m
        for (int i = 0; i < l; i++) {
            M_m[i] = M / m[i];
        }
        //遍历M / m
        for (int i = 0; i < l; i++) {
            System.out.println("M / m_"+(i+1)+" = "+M_m[i]);
        }


        //3.求Y
        int y = 1;
        boolean bool = true;
        int[] Y = new int[l];//存Y值
        for (int i = 0; i < l; i++) {
            while (bool) {
                if (((M_m[i]) * y - 1) % m[i] == 0) {//求Y值的核心算法
                    Y[i] = y;
                    break;
                } else {
                    y++;
                }
            }
        }
        //遍历Y
        for (int i = 0; i < l; i++) {
            System.out.println("Y_"+(i+1)+ "= "+Y[i]);
        }


        //4.求最终结果
        int end = 0;
        for (int i = 0; i < l; i++) {
            end += M_m[i] * Y[i] * b[i];
        }

        System.out.println("结果为:"+end%M);

    }
    
}

RSA算法实现

package js;
 
import java.util.Scanner;
 
public class RSA {
    //判断是否是素数
    public static boolean isPrime(long n) {
        boolean b = true;
        for (long i = 2; i <= Math.sqrt(n); i++) {
            if (n % i == 0) {
                b = false;
                break;
            } else
                b = true;
        }
        return b;
    }
 
    //计算欧拉数
    public static long Euler(long p, long q) {
        return (p - 1) * (q - 1);
    }
 
    //欧几里得算法求两数的最大公因数---a>b
    static long gcd(long a, long b) {
        if (a < b) {
            long t = a;
            a = b;
            b = t;
        }
        if (a % b == 0) return b;
        else return gcd(b, a % b);
    }
 
    //求模反元素d(私钥)
    public static long Key(long e, long euler) {
        long key = 1;
        while ((key * e) % euler != 1) {
            key++;
        }
        return key;
    }
 
    //递归求n次方
    public static long power(long a, long n) {
        long r = 1;
        if (n == 0) r = 1;
        else {
            r = a * power(a, n - 1);
        }
        return r;
    }
 
    //加密
    public static long encryption(long msg, long e, long n) {
        System.out.println("加密中.......");
        return power(msg, e) % n;
    }
 
    //解密
    public static long decryption(long c, long key, long n) {
        System.out.println("解密中.......");
        return power(c, key) % n;
    }
 
    public static void main(String[] args) {
        System.out.println("--------RSA--------");
        //两个大素数
        long p;
        long q;
        System.out.print("输入两个大素数p、q:");
        Scanner sc = new Scanner(System.in);
        p = sc.nextLong();
        q = sc.nextLong();
        // System.out.println("p = " + p + ",q = " + q);
        //判断输入的是否是素数
        boolean b;   //flag
        //判断p
        b = isPrime(p);
        if (b == false) {
            System.out.println("p = " + p + "不是素数。重新输入p!");
            p = sc.nextLong();
            b = isPrime(p);
            while (b = false) {
                System.out.println("p = " + p + "不是素数。重新输入p!");
                p = sc.nextLong();
                b = isPrime(p);
            }
        }
        System.out.println(" p = " + p + "是素数。");
 
        //判断q
        b = isPrime(q);
        if (b == false) {
            System.out.println("q = " + q + "不是素数。重新输入q!");
            q = sc.nextLong();
            b = isPrime(q);
            while (b = false) {
                System.out.println("q = " + q + "不是素数。重新输入q!");
                q = sc.nextLong();
                b = isPrime(q);
            }
        }
        System.out.println(" q = " + q + "是素数。");
        //打印最终的p、q
        System.out.println("p = " + p + ",q = " + q);
 
        //计算p、q的欧拉数
        long euler = Euler(p, q);
        System.out.println("Euler(p,q) = " + euler);
 
        //选取最小的公钥e,1<e<euler,且与euler互质
        long e = 2;
        while (gcd(e, euler) != 1 || e > euler || e < 1) {
            e++;
        }
        System.out.println("e = " + e);
 
        //求出模反元素(私钥)
        long key = Key(e, euler);
        System.out.println("key = " + key);
 
        //System.out.println(power(2, 2));
        //加密过程
        System.out.println("输入明文:");
        long msg = sc.nextLong();
        System.out.println("明文:" + msg);
        long c = encryption(msg, e, p * q);//密文
        System.out.println("加密后的密文:" + c);
        //解密过程
        msg = decryption(c, key, p * q);
        System.out.println("解密后的明文:" + msg);
 
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超翔之逸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值