Java实现RSA加密算法

该博客介绍了一个使用RSA算法进行文件加密和解密的Java实现,包括大数运算如加法、减法、乘法、除法和幂运算。代码中存在性能问题,因为使用了低效的数据表示和计算方式。提出通过使用更高进制(如256进制)来提升运算速度,以加快加解密过程。
摘要由CSDN通过智能技术生成

一、功能实现

1、可以加密任何文件
2、可以加密文件夹并保持文件夹目录层次不变
3、实现大数运算

二、代码实现

import java.io.*;
import java.math.BigInteger;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.Arrays;
import java.util.Random;

public class RSA {

    public static int MAX_DECIMAL_DIGIT = 9999;

    /**
     * 随机取大素数1
     * @return
     */
    public static BigInteger bigIntegerPrime() {
        BigInteger p;
        Random random = new Random();
        p = BigInteger.probablePrime(1024, random);//128加密30字节,256加密60字节,360加密80字节
        return p;
    }

    /**
     * 随机取大素数2
     * @return
     */
    public static int[] getPrimeNumber() {
        BigInteger bigInteger = bigIntegerPrime();
        char[] chars = String.valueOf(bigInteger).toCharArray();
        int[] result = new int[chars.length];
        for (int i = 0; i < chars.length; i++)
            result[i] = chars[i] - 48;
        return result;
    }

    /**
     * 判断大小
     *
     * @param a
     * @param b
     * @return
     */
    public static int judgeSize(int[] a, int[] b) {
        int i, j;
        int flag = 0;//flag = 0代表相等
        int len1, len2;

        for (i = 0; i < a.length; i++) {
            if (a[i] != 0)
                break;
        }
        len1 = a.length - i;//防止a的前i位是0从而影响判断,len1是去掉0后的实际长度
        int[] temp_a = new int[len1];
        System.arraycopy(a, i, temp_a, 0, len1);
        if (temp_a.length == 0)
            temp_a = new int[]{0};

        for (j = 0; j < b.length; j++) {
            if (b[j] != 0)
                break;
        }
        len2 = b.length - j;
        int[] temp_b = new int[len2];
        System.arraycopy(b, j, temp_b, 0, len2);
        if (temp_b.length == 0)
            temp_b = new int[]{0};

        if (temp_a[0] >= 0 && temp_b[0] >= 0) {
            if (len1 < len2) {
                flag = -1;//a<b返回-1
            } else if (len1 > len2) {
                flag = 1;
            } else {//长度相等时,逐位比较
                for (i = 0; i < temp_a.length; i++) {
                    if (temp_a[i] < temp_b[i]) {
                        flag = -1;
                        break;
                    }
                    if (temp_a[i] > temp_b[i]) {
                        flag = 1;
                        break;
                    }
                }
            }

        }
        if (temp_a[0] < 0 && temp_b[0] < 0) {
            if (len1 > len2) {
                flag = -1;
            } else if (len1 < len2) {
                flag = 1;
            } else if (len1 == len2 && temp_a[0] == temp_b[0]) {//长度相等时,逐位比较
                for (i = 1; i < temp_a.length; i++) {
                    if (temp_a[i] > temp_b[i]) {
                        flag = -1;
                        break;
                    }
                    if (temp_a[i] < temp_b[i]) {
                        flag = 1;
                        break;
                    }
                }
            } else if (len1 == len2 && temp_a[0] > temp_b[0]) {
                flag = 1;
            } else {
                flag = -1;
            }
        }
        if (temp_a[0] < 0 && temp_b[0] >= 0) {
            flag = -1;
        }
        if (temp_a[0] >= 0 && temp_b[0] < 0) {
            flag = 1;
        }
        return flag;
    }

    /**
     * 加法
     *
     * @param a
     * @param b
     * @return
     */
    public static int[] add(int[] a, int[] b) {
        int[] temp;
        int[] max;
        int[] min;
        int[] result;
        int[] result2;
        int i;
        int gap;
        int base = 0;//base记录进位
        int flag = 0;
        int[] temp_a = new int[a.length];
        System.arraycopy(a, 0, temp_a, 0, a.length);
        int[] temp_b = new int[b.length];
        System.arraycopy(b, 0, temp_b, 0, b.length);

        if ((temp_a[0] >= 0 && temp_b[0] >= 0) || (temp_a[0] < 0 && temp_b[0] < 0)) {
            if (temp_a[0] < 0 && temp_b[0] < 0)
                flag = 1;
            temp_a[0] = Math.abs(temp_a[0]);
            temp_b[0] = Math.abs(temp_b[0]);

            if (temp_a.length < temp_b.length) {
                temp = temp_a;
                temp_a = temp_b;
                temp_b = temp;
            }
            max = new int[temp_a.length];
            min = new int[max.length];
            result = new int[max.length];
            gap = temp_a.length - temp_b.length;
            System.arraycopy(temp_a, 0, max, 0, temp_a.length);
            System.arraycopy(temp_b, 0, min, gap, temp_b.length);
            for (i = max.length - 1; i >= 0; i--) {
                result[i] = max[i] + min[i] + base;
                base = 0;
                if (result[i] >= 10) {
                    result[i] = result[i] - 10;
                    base = 1;
                }
            }
            //如果最后结束的时候进位base==1,说明最终结果的位数比max多1,且第一位是1
            if (base == 1) {
                result2 = new int[result.length + 1];
                result2[0] = 1;
                System.arraycopy(result, 0, result2, 1, result.length);
                if (flag == 1)
                    result2[0] = -result2[0];
                return result2;
            } else {
                if (flag == 1)
                    result[0] = -result[0];
                return result;
            }
        } else if (temp_a[0] >= 0 && temp_b[0] < 0) {
            temp_b[0] = Math.abs(temp_b[0]);
            result = subtract_negative(temp_a, temp_b);
        } else {
            temp_a[0] = Math.abs(temp_a[0]);
            result = subtract_negative(temp_b, temp_a);
        }
        return result;
    }

    /**
     * 减法。计算不出负数
     *
     * @param a
     * @param b
     * @return
     */
    public static int[] subtract(int[] a, int[] b) {
        int i, j;
        int len1, len2;
        int[] temp;
        int[] max;
        int[] min;
        int[] result;
        int gap;
        int base = 0;//base记录进位

        for (i = 0; i < a.length; i++) {
            if (a[i] != 0)
                break;
        }
        len1 = a.length - i;//防止a的前i位是0从而影响判断,len1是去掉0后的实际长度
        int[] temp_a = new int[len1];
        System.arraycopy(a, i, temp_a, 0, len1);

        for (j = 0; j < b.length; j++) {
            if (b[j] != 0)
                break;
        }
        len2 = b.length - j;
        int[] temp_b = new int[len2];
        System.arraycopy(b, j, temp_b, 0, len2);

        if (len1 < len2) {
            temp = temp_a;
            temp_a = temp_b;
            temp_b = temp;
        }
        if (len1 == len2) {
            for (i = 0; i < temp_a.length; i++) {
                if (temp_a[i] < temp_b[i]) {
                    temp = temp_a;
                    temp_a = temp_b;
                    temp_b = temp;
                    break;
                }
                if (temp_a[i] > temp_b[i]) {
                    break;
                }
            }
        }
        if (temp_b.length == 0)
            temp_b = new int[1];

        max = new int[temp_a.length];
        min = new int[max.length];
        result = new int[max.length];
        gap = temp_a.length - temp_b.length;
        System.arraycopy(temp_a, 0, max, 0, temp_a.length);
        System.arraycopy(temp_b, 0, min, gap, temp_b.length);
        for (i = max.length - 1; i >= 0; i--) {
            result[i] = max[i] - min[i] - base;
            base = 0;
            if (result[i] < 0) {
                result[i] = result[i] + 10;
                base = 1;
            }
        }
        for (i = 0; i < result.length; i++) {
            if (result[i] != 0)
                break;
        }
        if (i == result.length)
            return new int[]{0};
        int[] result2 = new int[result.length - i];
        for (j = 0; i < result.length; j++, i++)
            result2[j] = result[i];
        return result2;
    }

    /**
     * 减法。负数间计算
     *
     * @param a
     * @param b
     * @return
     */
    public static int[] subtract_negative(int[] a, int[] b) {
        int i, j;
        int len1, len2;
        int[] temp;
        int[] t;

        int flag = 0;

        for (i = 0; i < a.length; i++) {
            if (a[i] != 0)
                break;
        }
        len1 = a.length - i;//防止a的前i位是0从而影响判断,len1是去掉0后的实际长度
        int[] temp_a = new int[len1];
        System.arraycopy(a, i, temp_a, 0, len1);
        if (temp_a.length == 0)
            temp_a = new int[]{0};

        for (j = 0; j < b.length; j++) {
            if (b[j] != 0)
                break;
        }
        len2 = b.length - j;
        int[] temp_b = new int[len2];
        System.arraycopy(b, j, temp_b, 0, len2);
        if (temp_b.length == 0)
            temp_b = new int[]{0};

        if (temp_a[0] >= 0 && temp_b[0] < 0) {
            temp_b[0] = -temp_b[0];
            return add(temp_a, temp_b);
        }

        if (temp_a[0] < 0 && temp_b[0] >= 0) {
            temp_a[0] = -temp_a[0];
            t = add(temp_a, temp_b);
            t[0] = -t[0];
            return t;
        }

        if (temp_a[0] >= 0 && temp_b[0] >= 0) {
            if (len1 < len2) {
                t = subtract(temp_a, temp_b);
                t[0] = -t[0];
                return t;
            }
            if (len1 == len2) {
                for (i = 0; i < temp_a.length; i++) {
                    if (temp_a[i] < temp_b[i]) {
                        t = subtract(temp_a, temp_b);
                        t[0] = -t[0];
                        return t;
                    }
                    if (temp_a[i] > temp_b[i]) {
                        return subtract(temp_a, temp_b);
                    }
                }
                if (i == temp_a.length)
                    return new int[]{0};
            }
            if (len1 > len2) {
                return subtract(temp_a, temp_b);
            }
        }

        if (temp_a[0] < 0 && temp_b[0] < 0) {
            temp_a[0] = -temp_a[0];
            temp_b[0] = -temp_b[0];
            if (len1 < len2 || (len1 == len2 && temp_a[0] < temp_b[0])) {
                return subtract(temp_a, temp_b);
            }
            if (len1 > len2 || (len1 == len2 && temp_a[0] > temp_b[0])) {
                t = subtract(temp_a, temp_b);
                t[0] = -t[0];
                return t;
            }
            if (len1 == len2) {
                for (i = 1; i < temp_a.length; i++) {
                    if (temp_a[i] > temp_b[i]) {
                        t = subtract(temp_a, temp_b);
                        t[0] = -t[0];
                        return t;
                    }
                    if (temp_a[i] < temp_b[i]) {
                        return subtract(temp_a, temp_b);
                    }
                }
            }
        }
        return new int[]{0};

    }

    /**
     * 乘法
     *
     * @param a
     * @param b
     * @return
     */
    public static int[] multi(int[] a, int[] b) {
        int t;

        if (a.length == 0)
            a = new int[]{0};
        if (b.length == 0)
            b = new int[]{0};

        int[] temp_a = new int[a.length];
        int[] temp_b = new int[b.length];
        System.arraycopy(a, 0, temp_a, 0, a.length);
        System.arraycopy(b, 0, temp_b, 0, b.length);


        temp_a[0] = Math.abs(temp_a[0]);
        temp_b[0] = Math.abs(temp_b[0]);
        for (int i = 0; i < temp_a.length / 2; i++) {
            t = temp_a[i];
            temp_a[i] = temp_a[temp_a.length - 1 - i];
            temp_a[temp_a.length - 1 - i] = t;
        }
        for (int i = 0; i < temp_b.length / 2; i++) {
            t = temp_b[i];
            temp_b[i] = temp_b[temp_b.length - 1 - i];
            temp_b[temp_b.length - 1 - i] = t;
        }

        //预先声明一个数组,用来存放各个位数相乘的结果(类似于列竖式)
        int len = temp_a.length + temp_b.length;
        int[] array = new int[len];

        //m位数和n位数相乘,得到的结果的位数只能是m+n-1或者m+n。
        //把m+n位设置为-1,用来标记最终结果到底是多少位。
        array[len - 1] = -1;

        //模拟竖式计算
        int base = 0;//存储进位
        int temp;
        for (int i = 0, j; i < temp_b.length; i++) {
            base = 0; //进位归位
            for (j = 0; j < temp_a.length; j++) {
                temp = (temp_b[i]) * (temp_a[j]) + base + array[i + j];
                array[i + j] = temp % 10;
                base = temp / 10;
            }
            if (base != 0)
                array[i + j] = base;
        }
        StringBuffer str = arrayFormat(array);
        char[] nums = str.toString().toCharArray();
        int[] result = new int[nums.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = nums[i] - 48;
        }
        if ((a[0] >= 0 && b[0] >= 0) || (a[0] < 0 && b[0] < 0))
            return result;
        else
            result[0] = -result[0];
        return result;
    }

    /**
     * 和乘法配合用
     *
     * @param array
     * @return
     */
    public static StringBuffer arrayFormat(int[] array) {
        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < array.length - 1; i++) {
            buffer.append(array[i]);
        }
        if (array[array.length - 1] != -1)
            buffer.append(array[array.length - 1]);
        return buffer.reverse();
    }

    /**
     * 除法
     *
     * @param a
     * @param b
     * @return
     */
    public static int[] divide(int[] a, int[] b) {
        int flag_a = 0;
        int flag_b = 0;
        if (a[0] < 0) {
            a[0] = -a[0];
            flag_a = 1;
        }
        if (b[0] < 0) {
            b[0] = -b[0];
            flag_b = 1;
        }


        int i, j, k;
        int[] diff = new int[b.length - 1];
        int[] t1 = new int[b.length];
        int[] temp = new int[a.length];
        System.arraycopy(a, 0, temp, 0, a.length);
        int[] result = new int[a.length];
        if (judgeSize(a, b) == -1)
            return new int[]{0};
        if (Arrays.equals(subtract(a, b), new int[]{0})) {
            return new int[]{1};
        }
        for (k = 0; k < b.length - 1; k++) {
            result[k] = 0;
        }
        for (j = k; j < a.length; j++) {
            int len1 = temp.length;
            int len2 = diff.length + 1;
            System.arraycopy(temp, 0, t1, 0, len2);
            while (judgeSize(t1, b) == -1) {
                result[j] = 0;
                j++;
                if (temp.length < len2 + 1)
                    len2 = temp.length - 1;
                t1 = new int[len2 + 1];
                System.arraycopy(temp, 0, t1, 0, len2 + 1);
                if (j == a.length) {
                    break;
                }
                len2++;
            }
            if (j == a.length)
                break;
            for (i = 1; i <= 9; i++) {
                if ((judgeSize(multi(b, new int[]{i}), t1) == -1 || judgeSize(multi(b, new int[]{i}), t1) == 0) && judgeSize(multi(b, new int[]{i + 1}), t1) == 1) {
                    result[j] = i;
                    if (judgeSize(multi(b, new int[]{i}), t1) == 0)
                        diff = new int[0];
                    else
                        diff = subtract(t1, multi(b, new int[]{i}));
                    break;
                }
            }

            int[] t2 = new int[len1 - t1.length + diff.length];
            System.arraycopy(diff, 0, t2, 0, diff.length);
            System.arraycopy(temp, t1.length, t2, diff.length, len1 - t1.length);
            temp = new int[t2.length];//temp是后面的数
            System.arraycopy(t2, 0, temp, 0, t2.length);
            t1 = new int[diff.length + 1];//t1是差+后面数的第一位
        }
        for (i = 0; i < result.length; i++) {
            if (result[i] != 0) {
                break;
            }
        }
        int[] result2 = new int[result.length - i];
        System.arraycopy(result, i, result2, 0, result.length - i);
        if ((flag_a == 0 && flag_b == 0) || (flag_a == 1 && flag_b == 1)) {
            if (flag_a == 1 && flag_b == 1) {
                a[0] = -a[0];
                b[0] = -b[0];
            }
            return result2;
        } else if (flag_a == 0 && flag_b == 1) {
            b[0] = -b[0];
            result2[0] = -result2[0];
            return result2;
        } else {
            a[0] = -a[0];
            result2[0] = -result2[0];
            return result2;
        }
    }

    /**
     * 求余
     *
     * @param a
     * @param b
     * @return
     */
    public static int[] mod(int[] a, int[] b) {
        int[] divide_result = divide(a, b);
        int[] multi_result = multi(b, divide_result);
        int[] result = subtract(a, multi_result);
        return result;
    }

    /**
     * 幂运算
     *
     * @param a
     * @param b
     * @return
     */
    public static int[] pow(int[] a, int[] b) {
        int[] t = a;
        int[] result = new int[MAX_DECIMAL_DIGIT];//2的1024次方有309位,所以这个二进制转十进制不可能超过350位
        if (judgeSize(b, new int[]{0}) == 0) {
            return new int[]{1};
        } else if (judgeSize(b, new int[]{1}) == 0)
            return a;
        else {
            for (int[] i = new int[]{1}; judgeSize(i, b) == -1; i = add(i, new int[]{1})) {
                result = multi(a, t);
                a = result;
            }
            return result;
        }
    }

    /**
     * 二进制转大数
     *
     * @param birnary
     * @return
     */
    public static int[] BirnaryToBiginteger(int[] birnary) {
        int i, j;
        int[] p = new int[]{0};
        int[] pow;
        int[] decimal = new int[MAX_DECIMAL_DIGIT];
        for (i = birnary.length - 1; i >= 0; i--) {
            pow = pow(new int[]{2}, p);
            decimal = add(multi(pow, new int[]{birnary[i]}), decimal);
            p = add(p,new int[]{1});
        }
        for (i = 0; decimal[i] == 0; i++) {
        }//由于decimal的前n位都是0,所以这个for是用于找到第一个不为0的数,从这个数开始就是上方的运算结果
        int[] result = new int[MAX_DECIMAL_DIGIT - i];
        for (j = 0; i != MAX_DECIMAL_DIGIT; j++, i++)
            result[j] = decimal[i];
        return result;
    }

    /**
     * 大数转二进制
     * @param c
     * @return
     */
    public static int[] BigintegerToBirnary(int[] c) {
        int[] temp = new int[MAX_DECIMAL_DIGIT];
        int i = 0;
        while (true) {
            temp[i] = c[c.length - 1] % 2;
            c = divide(c,new int[]{2});
            if (judgeSize(c,new int[]{0}) == 0)
                break;
            i++;
        }
        int n = 8 - (i + 1) % 8;//补足8*n位,为下面的字节流转换做准备
        if (n == 8)//补1~7位就够了,防止补8位
            n = 0;
        int[] birnary = new int[i + 1 + n];
        int j;
        for (j = 0; j < n; j++) {
            birnary[j] = 0;
        }
        while (j < birnary.length) {
            birnary[j] = temp[i];
            j++;
            i--;
        }
        return birnary;
    }

    /**
     * 公钥指数E定为3、17、65537
     * 因为3、17或65537分别只需要2或17次模乘运算,而一个随机选择的e(假设n是1024-bit)则大约需要1000次模乘运算。这种方法刻意把公钥指数选的小一点,其对应私钥指数就会很大,这么做的目的是节约公钥运算的时间。
     *
     * @param sn
     * @return
     */
    public static int[] getE(int[] sn) {
        if (judgeSize(mod(sn, new int[]{3}), new int[]{0}) != 0)//sn%3!=0
            return new int[]{3};
        if (judgeSize(mod(sn, new int[]{7}), new int[]{0}) != 0)//sn%3!=0
            return new int[]{7};
        if (judgeSize(mod(sn, new int[]{11}), new int[]{0}) != 0)//sn%17!=0
            return new int[]{11};
        if (judgeSize(mod(sn, new int[]{13}), new int[]{0}) != 0)//sn%17!=0
            return new int[]{13};
        if (judgeSize(mod(sn, new int[]{17}), new int[]{0}) != 0)//sn%17!=0
            return new int[]{17};
        if (judgeSize(mod(sn, new int[]{19}), new int[]{0}) != 0)//sn%17!=0
            return new int[]{19};
        if (judgeSize(mod(sn, new int[]{65537}), new int[]{0}) != 0)//sn%65537!=0
            return new int[]{65537};
        return new int[]{1};
    }

    /**
     * 求D
     *
     * @param a
     * @param b
     * @return
     */
    public static int[] getD(int[] a, int[] b) {
        int[][] m = {{1}, {0}, a};
        int[][] n = {{0}, {1}, b};
        int[][] temp = new int[3][];
        int[] q;
        boolean flag = true;
        while (flag) {
            q = divide(m[2], n[2]);
            for (int i = 0; i < 3; i++) {
                temp[i] = subtract_negative(m[i], multi(q, n[i]));//temp[i] = m[i] - q * n[i]
                m[i] = n[i];
                n[i] = temp[i];
            }
            if (judgeSize(n[2], new int[]{1}) == 0) {
                if (judgeSize(n[1], new int[]{0}) == -1) {
                    n[1] = add(n[1], a);
                }
                return n[1];
            }
            if (judgeSize(n[2], new int[]{0}) == 0) {
                flag = false;
            }
        }
        return new int[]{0};
    }

    /**
     * 求C
     * @param m
     * @param e
     * @param n
     * @return
     */
    public static int[] getC(int[] m, int[] e, int[] n) {
        int[] c;
        c = modpow(m,e,n);//返回其值为 (m^e  mod n)
        return c;
    }

    /**
     * 解密
     * @param c
     * @param n
     * @param d
     * @return
     */
    public static int[] getDecrypt(int[] c, int[] n, int[] d) {
        int[] m;
        m = modpow(c,d,n);//返回其值为 (c^d  mod n)
        return m;
    }

    /**
     * 快速模幂运算,如果不用此办法,运算就会很慢很慢
     * @param base
     * @param a
     * @param mod
     * @return
     */
    public static int[] modpow(int[] base, int[] a, int[] mod) {
        int[] ans = new int[]{1};
        int[] m;
        int[] n;
        base = mod(base,mod);
        while (judgeSize(a, new int[]{0}) != 0) {
            if (a[a.length - 1] % 2 == 1) {
                m = multi(ans, base);
                ans = mod(m, mod);
            }
            n = multi(base, base);
            base = mod(n, mod);
            a = divide(a, new int[]{2});
        }
        return ans;
    }

    /**
     * 字节流转二进制
     * @param intdata
     * @return
     */
    public static int[] ReadDataToBirnaryIntArray(byte[] intdata) {
        int i;
        int j;
        int[] IntDa = new int[intdata.length];
        int[] IntVa = new int[intdata.length * 8];
        // 将数据转换为二进制数,存储到数组
        for (i = 0; i < intdata.length; i++) {
            IntDa[i] = intdata[i];
            if (IntDa[i] < 0) {
                IntDa[i] += 256;
                IntDa[i] %= 256;
            }
        }
        //除2的方式
        for (i = 0; i < intdata.length; i++) {
            for (j = 0; j < 8; j++) {
                IntVa[((i * 8) + 7) - j] = IntDa[i] % 2;
                IntDa[i] = IntDa[i] / 2;
            }
        }
        return IntVa;
    }

    /**
     * 字节流读文件
     * @param path
     * @return
     */
    public static byte[] getFileByte(String path) {
        FileChannel fc = null;
        byte[] result = null;
        try {
            fc = new RandomAccessFile(path, "r").getChannel();
            MappedByteBuffer byteBuffer = fc.map(MapMode.READ_ONLY, 0,
                    fc.size()).load();
            result = new byte[(int) fc.size()];
            if (byteBuffer.remaining() > 0) {
                byteBuffer.get(result, 0, byteBuffer.remaining());
            }
        } catch (IOException e) {
            e.printStackTrace();

        } finally {
            try {
                fc.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 大数转二进制
     * @param data
     * @return
     */
    public static byte[] BirnaryIntArrayToInt(int[] data) {
        int i;
        int j;
        byte[] value = new byte[data.length / 8];
        for (i = 0; i < value.length; i++) {
            for (j = 0; j < 8; j++) {
                value[i] += (data[(i << 3) + j] << (7 - j));
            }
        }
        for (i = 0; i < value.length; i++) {
            value[i] %= 256;
            if (value[i] > 128) {
                value[i] -= 255;
            }
        }
        return value;
    }

    /**
     * 加解密时生成文件
     * @param c
     * @param filePath
     * @param fileName
     */
    public static void generateFile(int[] c, String filePath, String fileName) {
        int[] bigintegerToBirnary = BigintegerToBirnary(c);//解密转成二进制int数组
        byte[] bfile = BirnaryIntArrayToInt(bigintegerToBirnary);//二进制转成字节流
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try {
            File dir = new File(filePath);
            if (!dir.exists() && dir.isDirectory()) {//判断文件目录是否存在
                dir.mkdirs();
            }
            file = new File(filePath + "\\" + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(bfile);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

    /**
     * 读取文件
     * @param filepath
     * @param e
     * @param n
     * @param d
     * @throws IOException
     */
    public static void readfile(String filepath, int[] e, int[] n, int[] d) throws IOException {
        try {
            File file = new File(filepath);
            if (!file.isDirectory()) {
                byte[] fileByte = getFileByte(file.getAbsolutePath());//字节流读文件
                int[] fileByteToBirnary = ReadDataToBirnaryIntArray(fileByte);//字节流转换成二进制数组
                //step7:加密
                int[] m = BirnaryToBiginteger(fileByteToBirnary);//明文m
                int[] c = getC(m, e, n);//计算密文
                generateFile(c, "F:\\Desktop\\物联网安全\\密文", file.getName());
                //step8:进行解密
                int[] decrypt = getDecrypt(c,n,d);//进行解密
                generateFile(decrypt, "F:\\Desktop\\物联网安全\\解密", file.getName());
            } else if (file.isDirectory()) {
                String path1;//密文路径
                String path2;//解密路径
                path1 = filepath.replace("F:\\Desktop\\物联网安全\\明文", "F:\\Desktop\\物联网安全\\密文");
                path2 = filepath.replace("F:\\Desktop\\物联网安全\\明文", "F:\\Desktop\\物联网安全\\解密");
                File dir = new File(path1);
                if (!dir.exists()) {//判断文件目录是否存在
                    dir.mkdirs();
                }
                File dir2 = new File(path2);
                if (!dir2.exists()) {//判断文件目录是否存在
                    dir2.mkdirs();
                }
                String[] filelist = file.list();
                for (int i = 0; i < filelist.length; i++) {
                    File readfile = new File(filepath + "\\" + filelist[i]);
                    if (!readfile.isDirectory()) {
                        byte[] fileByte = getFileByte(readfile.getAbsolutePath());//字节流读文件
                        int[] fileByteToBirnary = ReadDataToBirnaryIntArray(fileByte);//字节流转换成二进制数组
                        //step7:加密
                        int[] m = BirnaryToBiginteger(fileByteToBirnary);//明文m
                        int[] c = getC(m, e, n);//计算密文

                        generateFile(c, path1, readfile.getName());
                        //step8:进行解密
                        int[] decrypt = getDecrypt(c,n,d);//进行解密
                        generateFile(decrypt, path2, readfile.getName());
                    } else if (readfile.isDirectory()) {
                        readfile(filepath + "\\" + filelist[i], e, n, d);
                    }
                }
            }
        } catch (FileNotFoundException exception) {
            System.out.println("readfile() Exception:" + exception.getMessage());
        }
    }

    public static void main(String[] args) throws IOException {

        int[] p = getPrimeNumber();
        int[] q = getPrimeNumber();

        int[] n = multi(p, q);//n=p*q
        int[] sn = multi(subtract(p, new int[]{1}), subtract(q, new int[]{1}));//sn=(p-1)*(q-1)
        int[] e = getE(sn);
        if (judgeSize(e, new int[]{1}) == 0) {//e=3 || e=17 || e=65537.e=1说明此次的sn与3,17,65537都不互质
            System.out.println("终止程序,重新运行");
            System.exit(0);
        }
        int[] d = getD(sn, e);
        System.out.println("p=" + Arrays.toString(p));
        System.out.println("q=" + Arrays.toString(q));
        System.out.println("n=" + Arrays.toString(n));
        System.out.println("sn=" + Arrays.toString(sn));
        System.out.println("e=" + Arrays.toString(e));
        System.out.println("d=" + Arrays.toString(d));

        try {
            readfile("F:\\Desktop\\物联网安全\\明文", e, n, d);
        } catch (FileNotFoundException exception) {
            System.out.println("readfile() Exception:" + exception.getMessage());
        }

        System.out.println("加解密成功,请到相应目录下查看");
    }
}

三、代码改进

上述代码的问题是,加解密非常非常慢。一个可以改进的思路是,使用8进制,16进制,256进制等等。上面代码的思路是,把读取的文件转成二进制流,使用int[]来存储并进行大数运算,可以发现,int[]中每一位存储都是0或1,也就是说如果存储十进制数257,那么需要int[10]。但是,如果使用256进制,只需要int[2],int[0]=1,int[1]=1,这样一来,运算速度会得到很大的提升。
由于代码是好久前写的,具体代码细节忘记了,所以可能举的例子不太恰当(或者与代码细节不符),但是,使用高进制的确可以提高运行速度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值