RSA加密解密-高精度算法,支持BigInteger的加减乘除,取模,左移右移,Miller-Rabin大素数判断,nextProbablePrime,compareTo,快速幂膜算法

前言

因为之前写实验,rsa加密没有来得及实现大数运算,颇为遗憾,假期赶工,又把它加为完善,基本无bug,MyBigInteger类与Java的BigInteger类的API基本一致,没有用法区别。实验演示先启动Server,后启动Client即可。

本实验遗憾之处在于本算法的除法效率较低,解密的时候需要1~2分钟才能解密出来,还得继续改进算法性能。
本算法加密实现采用自己实现的大数运算,判断大素数,使用gui图形界面,程序通信。
在这里插入图片描述

1⃣️MyBigInteger.java

package 实验3.useMyBigInteger;

import java.io.Serializable;
import java.util.Arrays;

/**
 * 支持14种运算
 * cloneValue        深复制一个MyBigInteger对象
 * negate()          求相反数
 * Miller-Rabin算法   判断大素数
 * nextProbablePrime 求比当前数字还要大的下一位素数
 * intValue,         把int[]存储的数字转换成为int类型
 * compareTo,        比较两个MyBigInteger大小
 * isEven,           判断奇偶
 * shiftRight,       右移
 * shiftLeft,        左移
 * mod,             取模
 * add,             加法,支持负数运算
 * sub,             减法,支持负数运算
 * multiply,        乘法,支持负数运算
 * div               除法,检查除零异常,
 * 运算
 */
public class MyBigInteger implements Serializable {
    /**
     * 除法输入样例:
     * MyBigInteger a=new MyBigInteger("53151821738927198473286587437589342790832904890327489632786581923479012834902798473289");
     * MyBigInteger b=new MyBigInteger("1228137489274987893278943");
     * MyBigInteger c=a.divide(b);
     * System.out.println(c);
     * c.printModRes();
     * 乘法输入样例:
     * MyBigInteger a = new MyBigInteger("12328913789217392179");
     * MyBigInteger b = new MyBigInteger("786786687");
     * System.out.println(a.multiply(b));
     * 减法输入样例:
     * MyBigInteger a = new MyBigInteger("12328913789217392179");
     * MyBigInteger b = new MyBigInteger("786786687");
     * System.out.println(a.subtract(b));
     */

    public static final MyBigInteger ONE_, TWO_, FOUR_, TEN_, ZERO_;
    private int end;//末尾数字的下标
    private int[] value;//当前数值的表示形式
    private static final int MAX = 5000;//最多计算5000位的数字,太大了会爆堆的,oom!!!!!!
    private boolean isNegative;//是否是负数
    private int[] divRes;//商
    private int[] modRes;//余数

    static {
        ONE_ = new MyBigInteger("1");
        TWO_ = new MyBigInteger("2");
        FOUR_ = new MyBigInteger("4");
        TEN_ = new MyBigInteger("10");
        ZERO_ = new MyBigInteger("0");

    }

    /**
     * 乘法,需要逆置字符串
     * 直接输入字符串的需要规定end
     *
     * @param s
     */
    public MyBigInteger(String s) {
        value = new int[MAX];
        if (s.contains("-")) {
            s = s.replaceAll("-", "");//存储数字的绝对值,并且isNegative记录为true,表示记录的是负数
            end = s.length();
            toNum(s.toCharArray());
            isNegative = true;
            divRes = new int[s.length() + 1];
            modRes = new int[s.length() + 1];
            return;
        }
        end = s.length();
        toNum(s.toCharArray());
        isNegative = false;
        divRes = new int[s.length() + 1];
        modRes = new int[s.length() + 1];
    }

    /**
     * 乘法
     * 第0位不使用
     * @param length
     */
    public MyBigInteger(int length) {
        value = new int[length + 1];
        end = length - 1;
        isNegative = false;

        divRes = new int[length + 1];
        modRes = new int[length + 1];
    }

    /**
     * 乘法
     * MyBigInteger a = new MyBigInteger("12328913789217392179");
     * MyBigInteger b = new MyBigInteger("786786687");
     * System.out.println(a.multiply(b));
     *
     * @param o
     * @return
     */
    public MyBigInteger multiply(MyBigInteger o) {
        if (o.end == 1 && o.value[1] == 0) {
            return new MyBigInteger("0");
        }
        if (end == 1 && value[1] == 0) {
            return new MyBigInteger("0");
        }
        MyBigInteger res = new MyBigInteger(end + o.end + 2);
        for (int i = 1; i <= end; i++) {
            for (int j = 1; j <= o.end; j++) {
                res.value[i + j - 1] += value[i] * o.value[j];
                res.value[i + j] += res.value[i + j - 1] / 10;
                res.value[i + j - 1] %= 10;
            }
        }
        while (res.value[res.end] == 0 && res.end > 0) {//删除多余的前面的0
            res.end--;
        }
        /**
         * 修正异号相乘的bug
         */
        if ((o.isNegative && this.isNegative) || ((!o.isNegative) && (!this.isNegative))) {
            return res;
        } else {
            res.isNegative = true;
            return res;
        }
    }

    /**
     * 字符数字转化位int类型的数字
     *
     * @param s
     */
    private void toNum(char[] s) {
        int i = s.length;
        for (var item : s) {// item 是char类型,转为int类型了
            value[i--] = (item - '0');// '0' -> 0, '1' -> 1
        }
    }

    public int[] getNum() {
        return value;
    }

    @Override
    public String toString() {
        StringBuilder s = new StringBuilder();
        if (isNegative) {
            s.append("-");
        }
        if (this.end == 0) {
            return "0";
        }
        for (int i = end; i > 0; i--) {
            s.append(value[i]);
        }

        return s.toString();
    }

    public int getLength() {
        return end;
    }



    @Override
    public int hashCode() {
        int result = end;
        result = 31 * result + (value != null ? Arrays.hashCode(this.value) : 0);
        result = 31 * result + (isNegative ? 1 : 0);
        return result;
    }


    /*四种特殊情况
    MyBigInteger i1=new MyBigInteger("2");
    MyBigInteger i2=new MyBigInteger("3");
    System.out.println("正-正"+i1.subtract(i2));

    MyBigInteger i3=new MyBigInteger("3");
    MyBigInteger i4=new MyBigInteger("-4");
    System.out.println("正-负"+i3.subtract(i4));

    MyBigInteger i5=new MyBigInteger("-5");
    MyBigInteger i6=new MyBigInteger("7");
    System.out.println("负-正"+i5.subtract(i6));

    MyBigInteger i7=new MyBigInteger("-3");
    MyBigInteger i8=new MyBigInteger("-8");
    System.out.println("负-负"+i7.subtract(i8));
     */

    public MyBigInteger subtract(MyBigInteger o) {
        return this.subtract(o, sub_cmp(this, o));
    }

    /**
     * this.subtract(o) => this-o
     * MyBigInteger a = new MyBigInteger("12328913789217392179");
     * MyBigInteger b = new MyBigInteger("786786687");
     * System.out.println(a.subtract(b,sub_cmp(a, b)));
     *
     * @param o
     * @return
     */

    private MyBigInteger subtract(MyBigInteger o, Boolean neg) {
        if (!this.isNegative && o.isNegative) {//正数-负数=>正数+正数
            o.isNegative = false;
            return this.add(o);
        }
        if (this.isNegative && !o.isNegative) { //负数-正数=>两个正数的和的相反数
            MyBigInteger copy1 = this.cloneValue();
            MyBigInteger copy2 = o.cloneValue();
            copy1.isNegative = false;
            copy2.isNegative = false;
            MyBigInteger res = copy1.add(copy2);
            res.isNegative = true;
            return res;
        }
        if (this.isNegative && o.isNegative) {//负数-负数,=> r变成正数,l变成正数,化为r-l处理
            MyBigInteger copy1 = this.cloneValue();
            MyBigInteger copy2 = o.cloneValue();
            copy1.isNegative = false;
            copy2.isNegative = false;
            return copy2.subtract(copy1);
        }
        MyBigInteger res = new MyBigInteger(Math.max(end, o.end) + 1);
        int[] copyChar = Arrays.copyOfRange(value, 0, value.length);
        int[] copyO = Arrays.copyOfRange(o.value, 0, o.value.length);

        if (!neg) {//如果neg是true,那就是a-b<0
            res.isNegative = true;
            int[] tmp = Arrays.copyOfRange(copyChar, 0, value.length);
            copyChar = Arrays.copyOfRange(copyO, 0, o.value.length);
            copyO = Arrays.copyOfRange(tmp, 0, tmp.length);
        }

        // 假设减法所用MyBigInteger的对象都是用MyBigInteger(String) 构造
        for (int i = 1; i <= res.end; i++) {
            if (copyChar[i] < copyO[i]) {
                copyChar[i + 1]--;
                copyChar[i] += 10;
            }
            res.value[i] = copyChar[i] - copyO[i];
        }
        while (res.value[res.end] == 0 && res.end > 1) {
            res.end--;
        }
        return res;
    }
    private static Boolean sub_cmp(MyBigInteger s1, MyBigInteger s2) {
        int u = s1.end, v = s2.end;
        if (u != v) {
            return u > v;//长度不一样
        }
        for (int i = u; i > 0; i--) {
            if (s1.getNum()[i] != s2.getNum()[i]) {
                return s1.getNum()[i] > s2.getNum()[i];//如果有一位不一样,则当减为负数时,返回true,a大于b返回false
            }
        }

        return true;//完全相等
    }
    /**
     * 返回1表示a>b,返回0表示a=b,返回-1表示a<b
     *
     * @param a
     * @param b
     * @return
     */
    private int div_cmp(MyBigInteger a, int[] b) {
        if (a.end > b[0]) {
            return 1;
        }
        if (a.end < b[0]) {
            return -1;
        }
        for (int i = a.end; i > 0; i--) {
            if (a.value[i] > b[i]) {
                return 1;
            }
            if (a.value[i] < b[i]) {
                return -1;
            }
        }
        return 0;
    }

    /**
     * 小于返回-1,等于返回0,大于返回1
     *
     * @param o
     * @return
     */
    public int compareTo(MyBigInteger o) {
        if (this.isNegative) {
            if (o.isNegative) {
                if (this.end > o.end) {//end表示有这个整数有几位?
                    return -1;
                }
                if (this.end < o.end) {
                    return 1;
                }
                for (int i = this.end; i > 0; i--) {
                    if (this.value[i] > o.value[i]) {
                        return -1;
                    }
                    if (this.value[i] < o.value[i]) {
                        return 1;
                    }
                }
                return 0;
            } else {
                return -1;
            }
        } else {
            if (o.isNegative) {
                return 1;
            }
            if (this.end > o.end) {
                return 1;
            }
            if (this.end < o.end) {
                return -1;
            }
            for (int i = this.end; i > 0; i--) {
                if (this.value[i] > o.value[i]) {
                    return 1;
                }
                if (this.value[i] < o.value[i]) {
                    return -1;
                }
            }
            return 0;
        }
    }

    /**
     * q[0]是表示q当前存储了多少个位数
     *
     * @param p 除数,比如A➗B,那p就是MyInteger的value
     * @param q 一个临时的数组
     * @param n 数组整体移动n位,123->123000
     */
    private static void copyNum(MyBigInteger p, int[] q, int n) {
        for (int i = 1; i <= p.end; i++) {
            q[i + n - 1] = p.value[i];
        }
        q[0] = p.end + n - 1;
    }

    private void minus(MyBigInteger a, int[] b) {
        for (int i = 1; i <= a.end; i++) {
            if (a.value[i] < b[i]) {
                a.value[i + 1]--;
                a.value[i] += 10;
            }
            a.value[i] -= b[i];
        }
        /**
         * 删除前面多余的0
         *
         */
        while (a.value[a.end] == 0 && a.end > 0) {
            a.end--;
        }
    }

    public boolean isEven() {
        return this.mod(TWO_).toString().equals("0");
    }

    /**
     * 拷贝一个MyBigInteger对象
     *
     * @return
     */
    public MyBigInteger cloneValue() {
        MyBigInteger res = new MyBigInteger("0");
        res.value = new int[MAX];
        if (this.isNegative) {
            res.end = this.end;
            res.isNegative = true;
            res.value = Arrays.copyOf(this.value, this.value.length + 1);
            divRes = new int[this.end + 1];
            modRes = new int[this.end + 1];
            return res;
        }
        res.end = this.end;
        res.value = Arrays.copyOf(this.value, this.value.length + 1);
        res.isNegative = false;
        divRes = new int[this.end + 1];
        modRes = new int[this.end + 1];
        return res;
    }
//    a = 3
//    p = 1000003
//    q = 1000033
//    n = 1000036000099
//    fn = 1000002
//    e = 11
//    d = 636365

    public MyBigInteger divide(MyBigInteger o) {
        if (o.end == 1 && o.value[o.end] == 0) {
            System.err.println("Error: divide by zero!!");
            throw new RuntimeException();
        }
        MyBigInteger copyThis = this.cloneValue();
        MyBigInteger res = new MyBigInteger(copyThis.end - o.end > 0 ? copyThis.end - o.end + 1 : 2);
        int[] tmp = new int[MAX];
        for (int i = res.end; i >= 1; i--) {
            Arrays.fill(tmp, 0);
            copyNum(o, tmp, i);
            while (div_cmp(copyThis, tmp) >= 0) {
                res.value[i]++;
                minus(copyThis, tmp);
            }
        }
        while (res.value[res.end] == 0 && res.end > 1) {//res.end至少是1,因为0还表示1位数
            res.end--;
        }
        res.divRes = Arrays.copyOfRange(res.value, 0, res.end);
        res.modRes = my_reverse(Arrays.copyOfRange(copyThis.value, 1, copyThis.end + 1));
        /**
         * 修正异号相除的bug
         *
         */
        if ((o.isNegative && this.isNegative) || ((!o.isNegative) && (!this.isNegative))) {
            return res;
        } else {
            res.isNegative = true;
            return res;
        }
    }

    private static int[] my_reverse(int[] a) {
        int i, t, n = a.length;
        for (i = 0; i < n / 2; i++) {
            t = a[i];
            a[i] = a[n - i - 1];
            a[n - i - 1] = t;
        }
        return a;
    }


    public void printModRes() {
        StringBuilder s = new StringBuilder();
        for (var item : modRes) {
            s.append(item);
        }
        System.out.println(s);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof MyBigInteger)) return false;

        MyBigInteger that = (MyBigInteger) o;

        if (isNegative != that.isNegative) return false;
        return this.hashCode() == that.hashCode();
    }


    public MyBigInteger negate() {
        MyBigInteger copy = this.cloneValue();
        copy.isNegative = (!copy.isNegative);
        return copy;
    }
    /*四种特殊情况
    MyBigInteger i1=new MyBigInteger("2");
    MyBigInteger i2=new MyBigInteger("3");
    System.out.println("正+正:"+i1.add(i2));

    MyBigInteger i3=new MyBigInteger("3");
    MyBigInteger i4=new MyBigInteger("-4");
    System.out.println("正+负:"+i3.add(i4));

    MyBigInteger i5=new MyBigInteger("-5");
    MyBigInteger i6=new MyBigInteger("7");
    System.out.println("负+正"+i5.add(i6));

    MyBigInteger i7=new MyBigInteger("-3");
    MyBigInteger i8=new MyBigInteger("-8");
    System.out.println("负+负"+i7.add(i8));
     */

    /**
     * 目前已解决所有BUG,欢迎爆破!!
     *
     * @param o
     * @return
     */
    public MyBigInteger add(MyBigInteger o) {
        if (!this.isNegative && o.isNegative) {//正数+负数
            MyBigInteger copy = o.cloneValue();
            copy.isNegative = false;
            return this.subtract(copy);
        }
        if (this.isNegative && !o.isNegative) {//负数+正数
            MyBigInteger copy1 = this.cloneValue();
            MyBigInteger copy2 = o.cloneValue();
            copy1.isNegative = false;
            return copy2.subtract(copy1);
        }
        if (this.isNegative && o.isNegative) {//负+负
            MyBigInteger copy1 = this.cloneValue();
            MyBigInteger copy2 = o.cloneValue();
            copy1.isNegative = copy2.isNegative = false;
            MyBigInteger res = copy1.add(copy2);
            res.isNegative = true;
            return res;
        }
        /**
         * 通用的正数+正数的情况
         */
        int max_bits_count = Math.max(this.end, o.end) + 1;
        MyBigInteger res = new MyBigInteger(max_bits_count + 1);
        for (int i = 1; i < max_bits_count; i++) {
            res.value[i] += (this.value[i] + o.value[i]);
            res.value[i + 1] = res.value[i] / 10;
            res.value[i] %= 10;
        }
        while (res.value[res.end] == 0 && res.end > 0) {
            res.end--;
        }
        return res;
    }

    public MyBigInteger shiftRight(int counts) {
        int num = 1 << counts;
        return this.divide(new MyBigInteger(num + ""));
    }

    public MyBigInteger shiftLeft(int counts) {
        int num = 1 << counts;
        return this.multiply(new MyBigInteger(num + ""));
    }

    /**
     * 容易int溢出
     *
     * @return 当前字符串的十进制int类型表示形式
     */
    public int intValue() {
        StringBuilder s = new StringBuilder();
        for (int i = this.end; i > 0; i--) {
            s.append(this.value[i]);
        }
        return Integer.valueOf(s.toString());
    }


    public MyBigInteger mod(MyBigInteger o) {
        MyBigInteger c = this.divide(o);
        int[] new_value = new int[MAX], reverse_array = my_reverse(c.modRes);
        new_value[0] = 0;
        c.end = reverse_array.length;
        for (int i = 1; i <= c.end; i++) {
            new_value[i] = reverse_array[i - 1];
        }
        if (reverse_array.length == 0) {
            c.end = 1;
        }
        c.value = new_value;
        Arrays.fill(c.modRes, 0);
        Arrays.fill(c.divRes, 0);
        return c;
    }

    /**
     * @param truth 底数
     * @param pow   指数
     * @return 大叔运算的结果!!!不管他有多少位,直接就是剥蒜!!!!!!
     */
    public static MyBigInteger power(int truth, int pow) {
        MyBigInteger res = new MyBigInteger(truth + "");
        MyBigInteger tmp = new MyBigInteger("1");
        for (int i = 1; i <= pow; i++) {
            tmp = res.multiply(tmp);
        }
        return tmp;
    }

    /**
     * 快速幂算法
     *
     * @param truth  底数
     * @param exp    指数
     * @param modNum 模数
     * @return
     */
    public static int quick_power(int truth, int exp, int modNum) {
        int ans = 1;
        truth %= modNum;
        while (exp > 0) {
            if ((exp & 1) != 0) {//奇数
                ans = (ans * truth) % modNum;
            }
            exp >>= 1;
            truth = (truth * truth) % modNum;
        }
        return ans;
    }

    /**
     * 快速幂(a^b)%c
     *
     * @param a 底数
     * @param b 幂
     * @param c 模数
     * @return
     */
    public static MyBigInteger Quick_Power(MyBigInteger a, MyBigInteger b, MyBigInteger c)     //快速幂
    {
        MyBigInteger ans = ONE_, res = a;
        while (b.compareTo(ZERO_) == 1) {
            if ((b.mod(TWO_).compareTo(ZERO_) != 0)) {
                ans = ans.multiply(res).mod(c);
            }
            res = res.multiply(res).mod(c);
            b = b.shiftRight(1);
        }
        return ans;
    }

    /**
     * 快速积
     *
     * @param a 乘数
     * @param b 被乘数
     * @param c 模数
     * @return
     */
    public static MyBigInteger Quick_Multiply(MyBigInteger a, MyBigInteger b, MyBigInteger c) {
        MyBigInteger ans = ZERO_, res = a;
        while (b.compareTo(ZERO_) != 0) {
            if (!b.isEven()) {
                ans = (ans.add(res)).mod(c);
            }
            res = (res.add(res)).mod(c);
            b = b.shiftRight(1);
        }
        return ans;
    }

    static int[] prime = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};

    public boolean probablePrime() {
        return Miller_Rabin(this);
    }

    public MyBigInteger nextProbablePrime() {
        MyBigInteger copy = this.cloneValue().add(ONE_);
        while (true) {
            if (copy.probablePrime()) {
                break;
            }
            copy = copy.add(ONE_);
        }
        return copy;
    }

    private boolean Miller_Rabin(MyBigInteger x) {   //判断素数
        MyBigInteger k;
        int i, j, s = 0;
        MyBigInteger t = x.subtract(ONE_);
        if (x.compareTo(TWO_) == 0) {
            return true;
        }
        if (x.compareTo(TWO_) < 0 || x.isEven()) {
            return false;
        }
        while (t.mod(TWO_).compareTo(ZERO_) == 0) {
            s++;
            System.out.println("t = " + t);
            t = t.shiftRight(1);//当采用13位及以上大素数时,容易时间复杂度翻车!!
        }
        i = 0;
        for (; i < 10 && new MyBigInteger(prime[i] + "").compareTo(x) < 0; i++) {
            MyBigInteger a = new MyBigInteger(prime[i] + "");
            MyBigInteger b = Quick_Power(a, t, x);
            for (j = 1; j <= s; j++) {
                k = Quick_Multiply(b, b, x);
                if (k.compareTo(ONE_) == 0 && b.compareTo(ONE_) != 0 && b.compareTo(x.subtract(ONE_)) != 0) {
                    return false;
                }
                b = k;
            }
            if (b.compareTo(ONE_) != 0) {
                return false;
            }
        }
        return true;
    }
}

2⃣️Server.java

package 实验3.useMyBigInteger;


import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedHashMap;
import java.util.LinkedList;

import static 实验3.useMyBigInteger.MyBigInteger.*;

public class Server extends JFrame {
    ServerSocket ss;
    Socket s;
    public static LinkedHashMap<String, Character> cmap;
    public static MyBigInteger e, n, q, a, d, p, fn;
    private JLabel cipherL, cnt;
    private JTextField cntF, ciF;
    private JButton getJB;
    private JPanel north;
    private JPanel center;
    private JPanel south;

    static {
        cmap = new LinkedHashMap<>();
        initMap();
        a = new MyBigInteger("3");
        p = generateNum();
        q = p.nextProbablePrime();
        n = p.multiply(q);
        fn = p.subtract(MyBigInteger.ONE_).multiply(q.subtract(MyBigInteger.ONE_));
        e = new MyBigInteger("5").nextProbablePrime();
        d = getInverseNum(e, fn);

        System.out.println("a = " + a);
        System.out.println("p = " + p);
        System.out.println("q = " + q);
        System.out.println("n = " + n);
        System.out.println("fn = " + fn);
        System.out.println("e = " + e);
        System.out.println("d = " + d);
// cybergatwall
    }

    public Server() {
        super("解密窗口🔓");
        try
        {
            cipherL = new JLabel("密文");
            cnt = new JLabel("明文");
            cntF = new JTextField(30);
            ciF = new JTextField(30);
            getJB = new JButton("了无㊙️密,一键解密🔓");
            north = new JPanel();
            center = new JPanel();
            south = new JPanel();

            north.add(cnt);
            north.add(cntF);
            center.add(cipherL);
            center.add(ciF);
            south.add(getJB);
            add(north, BorderLayout.NORTH);
            add(center, BorderLayout.CENTER);
            add(south, BorderLayout.SOUTH);
            pack();
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setVisible(true);
            ss = new ServerSocket(8888);
            s = ss.accept();

        } catch (Throwable e) {
            e.printStackTrace();
        }
        getJB.addActionListener(e -> {
            try {
                ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
                LinkedList<MyBigInteger> list = (LinkedList<MyBigInteger>) ois.readObject();
                StringBuilder ans = getPlainText(list);
                StringBuilder cipher = getCipher(list);
                ciF.setText(cipher.toString());
                cntF.setText(ans.toString());
            } catch (ClassNotFoundException c) {
                c.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        });

    }

    public static StringBuilder getPlainText(LinkedList<MyBigInteger> list) {
        StringBuilder s = new StringBuilder();
        MyBigInteger one_hundred = new MyBigInteger("100");
        for (var item : list) {
            MyBigInteger t = Quick_Power(item, d, n);
            char c1 = cmap.get(t.divide(one_hundred).toString());//HelloWorld
            char c2 = cmap.get(t.mod(one_hundred).toString());
            s.append(c1);
            s.append(c2);
        }
        return s;
    }

    public static StringBuilder getCipher(LinkedList<MyBigInteger> list) {
        StringBuilder s = new StringBuilder();
        for (var item : list) {
            s.append(item);
        }
        return s;
    }

    /**
     * 产生100位大素数
     *
     * @return
     */
    private static MyBigInteger generateNum() {
        MyBigInteger i = new MyBigInteger("1000000");
        return i.nextProbablePrime();
    }

    /**
     * a*a^-1 = 1 mod f
     *
     * @param a
     * @param f
     * @return f模a的乘法逆元
     *
     */
    private static MyBigInteger getInverseNum(MyBigInteger a, MyBigInteger f) {

        MyBigInteger l = f, r = a, i = ONE_, count = ZERO_;
        LinkedHashMap<String, String> q = new LinkedHashMap<>(), b = new LinkedHashMap<>();

        while (true) {
            MyBigInteger div = l.divide(r), reNum = l.mod(r);
            q.put(i.toString(), div.toString());
            count = count.add(ONE_);
            if (reNum.compareTo(ONE_) == 0) {
                break;
            }
            l = r;
            r = reNum;
            i = i.add(ONE_);
        }
        b.put(ONE_.negate().toString(), ZERO_.toString());
        b.put(ZERO_.toString(), ONE_.toString());
        MyBigInteger j = ONE_;
        for (; j.compareTo(count) == -1 || j.compareTo(count) == 0; j = j.add(ONE_)) {
            //下面是-1乘以。。。
            MyBigInteger left = ONE_.negate().multiply(new MyBigInteger(b.get(j.subtract(ONE_).toString()))).multiply(new MyBigInteger(q.get(j.toString())));
            MyBigInteger right = new MyBigInteger(b.get(j.subtract(TWO_).toString()));
            MyBigInteger res = left.add(right);
            b.put(j.toString(), res.toString());
        }
        MyBigInteger res = new MyBigInteger(b.get(j.subtract(ONE_).toString()));
        while (res.compareTo(ZERO_) == -1) {
            res = res.add(f);
        }
        return res;
    }

    public static void main(String[] args) {

        Server s=new Server();
        s.setVisible(true);
    }

    /**
     *
     * a->00
     * b->01
     * 建立字母整数映射表
     *
     */
    private static void initMap() {
        for (int i = 0; i < 26; i++) {
            cmap.put(new MyBigInteger(i + "").toString(), (char) (i + 'a'));
        }
        char[] c = new char[]{
                '!', '\"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',',
                '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', '@', '^',
                '<', '>', '?', ':', ';', '[', ']', '{', '}', '|', '\\', '~', '`'
        };
        for (int i = 33; i < 33 + c.length; i++) {
            cmap.put(new MyBigInteger(i + "").toString(), c[i - 33]);
        }
        System.out.println("The content of the map");
        for (var item : cmap.entrySet()) {
            System.out.println("key = " + item.getKey() + " value = " + item.getValue());
        }
    }
}

3⃣️Client.java

package 实验3.useMyBigInteger;


import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.LinkedHashMap;
import java.util.LinkedList;

public class Client extends JFrame {

    private Socket s;
    private JButton send;
    private JTextField plainText;
    private JLabel plainLabel;
    private JPanel north,center,south;
    private static LinkedHashMap<Character, String> cmap;


//  cybergatwall

    public Client(){
        super("加密窗口🔐");
        initMem();
        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }
    private void initMem(){
        try {
            s=new Socket("localhost",8888);
        } catch (IOException e) {
            e.printStackTrace();
        }
        send=new JButton("发送");
        plainText=new JTextField(20);
        plainLabel=new JLabel("明文");
        north=new JPanel();
        center=new JPanel();
        south=new JPanel();

        north.add(plainLabel);
        north.add(plainText);


        south.add(send);

        add(north,BorderLayout.NORTH);
        add(center,BorderLayout.CENTER);
        add(south,BorderLayout.SOUTH);
        send.addActionListener(e->{
            String iplain=plainText.getText().toLowerCase();
            LinkedList<MyBigInteger> cipherList=getCipher(iplain);
            ObjectOutputStream oos;
            try {
                oos=new ObjectOutputStream(s.getOutputStream());
                oos.writeObject(cipherList);
                oos.flush();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        });
    }
    /**
     * a->00
     * b->01
     * 建立字母整数映射表
     */
    private static void initMap() {
        for (int i = 0; i < 26; i++) {
            cmap.put((char)  (i+'a'), new MyBigInteger(i+"").toString());
        }
        char[] c=new char[]{
                '!','\"','#','$', '%','&' ,'\'','(',')' ,'*','+',',',
                '-','.','/','0','1','2','3','4','5','6','7','8','9',' ','@','^',
                '<','>','?',':',';','[',']','{','}','|','\\','~','`'
        };
        for (int i = 33; i < 33+c.length; i++) {
            cmap.put(c[i-33],new MyBigInteger(i+"").toString());
        }
    }

    static {
        cmap = new LinkedHashMap<>();
        initMap();
    }

    /**
     * 暂时忽略明文是奇数个字符的情况
     *
     * @param s 明文
     * @return 密文
     */
    public static LinkedList<MyBigInteger> getCipher(String s) {
        if (s.length()%2!=0){
            s=s+" ";
        }
        LinkedList<MyBigInteger> res = new LinkedList<>();
        for (int i = 0; i < s.length(); i += 2) {
            String t = s.substring(i, i + 2);
//            int i1 = cmap.get(t.charAt(0)), i2 = cmap.get(t.charAt(1));
//            int i3 = i1 * 100 + i2;
            MyBigInteger i1=new MyBigInteger(String.valueOf(cmap.get(t.charAt(0))));
            MyBigInteger i2=new MyBigInteger(String.valueOf(cmap.get(t.charAt(1))));
            MyBigInteger i3=i1.multiply(new MyBigInteger("100")).add(i2);
            MyBigInteger ans=MyBigInteger.Quick_Power(i3, Server.e, Server.n);
            res.addLast(ans);
        }
        for (var item : res)
        {
            System.out.println(" item = " + item);
        }
        return res;
    }

    public static void main(String[] args) {
        new Client();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hwg985

祝老板生意兴隆,财源广进

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

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

打赏作者

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

抵扣说明:

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

余额充值