2019.11.23:
这个代码一开始采用的是如《算法笔记》上等PAT中的类似题目将十进制数字转换为数组大整数(也是十进制形式)。
但是这种想法在后来实现加密的时候快速积出现了严重的弊端,和普通十进制并没有什么区别了,依旧拖慢进程大的可怕。
今天课设答辩同学们都做出了像毕设一样的作品,很完善的调用各种类实现各种混合加密,还有图形化界面,python、java、各种语言起飞。到了我这,可怜的连个运行起来都有问题。
下面的代码是256进制的刚起步,老师说不要这样转换,可以直接用long int类型读入(C++),然后直接转换为256进制。
我在下面的写法没有抛弃原来的10进制大整数。
#include <iostream>
#include <string>
#include<algorithm>
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;
/*1.生成密钥对,(e,d,n),公钥是(e,n),私钥是(d,n)
步骤如下:
求n(准备两个质数p,q。这两个数不能太小,太小则会容易破解,将p乘以q就是N),
求f=(p-1)(q-1)
求e :gcd(e,f)=1
求d:e*d mod f = 1
2.加密:用(e,n):密文 c=m^e(mod n)
3.解密:用(d,n):明文 m=c^d(mod n)
*/
//定义大整数结构体,使用保存十位数字每一位的方法
struct bigint{
int d[1000];
int len;
bigint(){
memset(d,0,sizeof(d));
len=0;
}
};
bigint e,d,p,q,n;
struct bigint256{
int d[32];
int len;
bigint256(){
memset(d,0,sizeof(d));
len=0;
}
};
int compare(bigint a,bigint b){//比较a和b的大小,a大、相等、a小分别返回1,0,-1
if(a.len>b.len)return 1;//a大
else if(a.len<b.len)return -1;//a小
else{
for(int i=a.len-1;i>=0;i--){
if(a.d[i]>b.d[i]) return 1;//只要有一位a大,则a大
else if(a.d[i]<b.d[i])return -1;//只要有一位a小,则a小
}
return 0;
}
}
void print(bigint a){
for(int i=a.len-1;i>=0;i--){
cout<<a.d[i];
}
}
//出错的原因:求解exgcd没有成功,是因为没有定义负数的运算!==
//重载大整数的运算
//进制转换需要转换为256进制
bigint change(char str[]){
bigint a;
a.len=strlen(str);
for(int i=0;i<a.len;i++){
a.d[i]=str[a.len-i-1]-'0';
}
return a;
}
char s0[3]="0";
char s1[3]="1";
char s2[3]="2";
char s3[3]="3";
bigint in0=change(s0);
bigint in1=change(s1);
bigint in2=change(s2);
bigint in3=change(s3);
//重载大整数减法
bigint operator - (bigint a, bigint b)
{
bigint temp;
int sign=1;
if(compare(a,b)<0){
temp=a;
a=b;
b=temp;
sign=-1;
}
//cout<<"a:";print(a);cout<<endl;
//cout<<"b:";print(b);cout<<endl;
bigint c;
int carry = 0;//carry是进位
for(int i=0;i<a.len||i<b.len;i++){//以较长的为界限
if(a.d[i]<b.d[i]){
a.d[i+1]--;//向高位借位
a.d[i]+=10;
}
c.d[c.len++]=a.d[i]-b.d[i];//减法结果为当前借位结果
}
while(c.len-1>=1&&c.d[c.len-1]==0){
c.len--;//去除高位的0,同时至少保留1位最低位
}
if(sign==1)return c;
else if(sign==-1){
c.d[c.len-1]=-c.d[c.len-1];
return c;
}
}
//重载高精度加法
bigint operator + ( bigint a, bigint b)
{
if(a.d[a.len-1]<0&&b.d[b.len-1]>0){
a.d[a.len-1]=-a.d[a.len-1];
return b-a;
}
if(a.d[a.len-1]>0&&b.d[b.len-1]<0){
b.d[b.len-1]=-b.d[b.len-1];
return a-b;
}
int sign=1;
if(a.d[a.len-1]<0&&b.d[b.len-1]<0){
b.d[b.len-1]=-b.d[b.len-1];
a.d[a.len-1]=-a.d[a.len-1];
sign=-1;
}
bigint c;
int carry = 0;//carry是进位
for(int i=0;i<a.len||i<b.len;i++){
int temp=a.d[i]+b.d[i]+carry;//两个对应位与进位相加
c.d[c.len++]=temp%10;
carry=temp/10;//十位数为新的进位
}
if(carry!=0){
c.d[c.len++]=carry;
}
while(c.len-1>=1&&c.d[c.len-1]==0){//清高位零
c.len--;}
if(sign==1)return c;
else if(sign==-1){
c.d[c.len-1]=-c.d[c.len-1];
return c;
}
}
//重载大整数除法
/*
思想:反复做减法,看从被除数里面最多能减去多少个除数,商就是多少。
*/
//重新写一个减法,适合于返回长度,将数组直接做减法,参数是bigint中数组
int SubStract( int *p1, int *p2, int len1, int len2 )
{
int i;
if( len1 < len2 )
return -1;