前言
因为之前写实验,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();
}
}