一、功能实现
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,这样一来,运算速度会得到很大的提升。
由于代码是好久前写的,具体代码细节忘记了,所以可能举的例子不太恰当(或者与代码细节不符),但是,使用高进制的确可以提高运行速度。