ClassBigInteger.h和python调用在之前博客里。
ClassBigInteger.cpp
#include "ClassBigInteger.h"
#include<bits/stdc++.h>
#include <string>
#include<iostream>
using namespace std;
BigInteger::BigInteger(){}
BigInteger::BigInteger(std::string num1):_num1(num1){}
BigInteger::BigInteger(char num1)
{
std::string cc="";
cc+=num1;
_num1=cc;
}
BigInteger::BigInteger(const BigInteger &bi)
{
_num1=bi._num1;
}
BigInteger::~BigInteger(){}
void BigInteger::setnum(std::string c){
this->_num1+=c;
}
void BigInteger::init(){
this->_num1="";
}
std::string BigInteger::toString() const
{
return _num1;
}
BigInteger BigInteger::operator+(const BigInteger &bi)
{
BigInteger t(*this);
t._num1=add(t._num1,bi._num1);
return t;
}
BigInteger BigInteger::operator-(const BigInteger &bi)
{
BigInteger t(*this);
t._num1=minus(t._num1,bi._num1);
return t;
}
BigInteger BigInteger::operator*(const BigInteger &bi)
{
BigInteger t(*this);
t._num1=multiply(t._num1,bi._num1);
return t;
}
BigInteger BigInteger::operator/(const BigInteger &bi)
{
BigInteger t(*this);
t._num1=divide(t._num1,bi._num1,0);
return t;
}
BigInteger BigInteger::operator%(const BigInteger &bi)
{
BigInteger t(*this);
t._num1=mod(t._num1,bi._num1);
return t;
}
int BigInteger::compare(std::string number1,std::string number2)
{
if(number1[0]!='-'&&number2[0]!='-'){
int j;
int length1 = number1.size();
int length2 = number2.size();
if(number1.size() == 0)
number1 = "0";
if(number2.size() == 0)
number2 = "0";
j = 0;
for(int i = 0; i < length1; ++i)
{
if(number1[i] == '0')
++j;
else
break;
}
number1 = number1.substr(j);
j = 0;
for(int i = 0; i < length2; ++i)
{
if(number2[i] == '0')
++j;
else
break;
}
number2 = number2.substr(j);
length1 = number1.size();
length2 = number2.size();
if(length1 > length2)
{
return 1;
}
else if(length1 == length2)
{
if(number1.compare(number2) > 0)
{
return 1;
}
else if(number1.compare(number2) == 0)
{
return 0;
}
else
{
return -1;
}
}
else
{
return -1;
}
}
else if(number1[0]=='-'&&number2[0]!='-')
{
return -1;
}
else if(number1[0]!='-'&&number2[0]=='-')
{
return 1;
}
else{
std::string absnumber1="";
std::string absnumber2="";
for(size_t i=1;i<number1.size();i++)
{
absnumber1+=number1[i];
}
for(size_t i=1;i<number2.size();i++)
{
absnumber2+=number2[i];
}
int result=compare(absnumber1,absnumber2);
if(result==1)
{
return -1;
}
else if(result==-1)
{
return 1;
}
else
{
return 0;
}
}
}
bool BigInteger::operator==(const BigInteger &a)const{
std::string s1=this->toString();
std::string s2=a.toString();
if(this->compare(s1,s2)==0)return true;
else return false;
}
bool BigInteger::operator>(const BigInteger &a)const{
std::string s1=this->toString();
std::string s2=a.toString();
if(this->compare(s1,s2)==1)return true;
else return false;
}
bool BigInteger::operator<(const BigInteger &a)const{
std::string s1=this->toString();
std::string s2=a.toString();
if(this->compare(s1,s2)==-1)return true;
else return false;
}
std::string BigInteger::add(std::string number1,std::string number2)
{
if(number1[0]!='-'&&number2[0]!='-'){
int i;
int length1 = number1.size();
int length2 = number2.size();
std::string result="";
reverse(number1.begin(), number1.end());
reverse(number2.begin(), number2.end());
for(i = 0; i < length1 && i < length2; i++)
{
char c = (char)(number1[i] + number2[i] - 48);//每一位相加,-48减去ascii的'0'
result = result + c;//把结果给result
}
//加上剩余比较长的数
while(i < length1)
{
result = result + number1[i];
++i;
}
while(i < length2)
{
result = result + number2[i];
++i;
}
//转化
int carry = 0;
for(i = 0; i < (int)result.size(); ++i)
{
int value = result[i] - 48 + carry;
result[i] = (char)(value % 10 + 48);
carry = value / 10;
}
if(carry !=0 )
{
result = result + (char)(carry + 48);
}
for(i = result.size() - 1; i >= 0; i--)
{
if(result[i] != '0')
break;
}
//截取有效位,有的数前面是用0来填充的
result = result.substr(0, i + 1);
//翻转回来
reverse(result.begin(), result.end());
if(result.length() == 0)
result = "0";
return result;
}
else if(number1[0]=='-'&&number2[0]!='-'){
std::string absnumber1="";
for(size_t i=1;i<number1.size();i++)
{
absnumber1+=number1[i];
}
std::string result=minus(number2,absnumber1);
return result;
}
else if(number1[0]!='-'&&number2[0]=='-'){
std::string absnumber2="";
for(size_t i=1;i<number2.size();i++)
{
absnumber2+=number2[i];
}
std::string result=minus(number1,absnumber2);
return result;
}
else
{
std::string absnumber1="";
std::string absnumber2="";
for(size_t i=1;i<number1.size();i++)
{
absnumber1+=number1[i];
}
for(size_t i=1;i<number2.size();i++)
{
absnumber2+=number2[i];
}
return "-"+add(absnumber1,absnumber2);
}
}
std::string BigInteger::minus(std::string number1,std::string number2)
{
if(number1[0]!='-'&&number2[0]!='-'){
int i;
std::string result = "";
int length1 = number1.size();
int length2 = number2.size();
if(compare(number2,number1) > 0)
{
return "-" + minus(number2, number1);
}
reverse(number1.begin(),number1.end());
reverse(number2.begin(),number2.end());
for(i = 0; i < length1 && i < length2; i++)
{
char c = number1[i] - number2[i] + 48;
result = result + c;
}
if(i < length1)
{
for(; i < length1; i++)
{
result = result + number1[i];
}
}
int carry = 0;
for(i = 0; i < (int)result.length(); i++)
{
int value = result[i] - 48 + carry;
if(value < 0)
{
value = value + 10;
carry = -1;
}
else
carry = 0;
result[i]=(char)(value + 48);
}
for(i = result.size() - 1; i >= 0; i--)
{
if(result[i] != '0')break;
}
result = result.substr(0, i+1);
reverse(result.begin(), result.end());
if(result.length()==0) result = "0";
return result;
}
else if(number1[0]=='-'&&number2[0]!='-'){
std::string absnumber1="";
for(size_t i=1;i<number1.size();i++)
{
absnumber1+=number1[i];
}
std::string result=add(number2,absnumber1);
return "-"+result;
}
else if(number1[0]!='-'&&number2[0]=='-'){
std::string absnumber2="";
for(size_t i=1;i<number2.size();i++)
{
absnumber2+=number2[i];
}
std::string result=add(number1,absnumber2);
return result;
}
else
{
std::string absnumber1="";
std::string absnumber2="";
for(size_t i=1;i<number1.size();i++)
{
absnumber1+=number1[i];
}
for(size_t i=1;i<number2.size();i++)
{
absnumber2+=number2[i];
}
return minus(absnumber2,absnumber1);
}
}
#define L(x) (1 << (x))
const double PI = acos(-1.0);
const int Maxn = 133015;
double ax[Maxn], ay[Maxn], bx[Maxn], by[Maxn];
char sa[Maxn/2],sb[Maxn/2];
int sum[Maxn];
int x1[Maxn],x2[Maxn];
int revv(int x, int bits)
{
int ret = 0;
for (int i = 0; i < bits; i++)
{
ret <<= 1;
ret |= x & 1;
x >>= 1;
}
return ret;
}
void fft(double * a, double * b, int n, bool rev)
{
int bits = 0;
while (1 << bits < n) ++bits;
for (int i = 0; i < n; i++)
{
int j = revv(i, bits);
if (i < j)
swap(a[i], a[j]), swap(b[i], b[j]);
}
for (int len = 2; len <= n; len <<= 1)
{
int half = len >> 1;
double wmx = cos(2 * PI / len), wmy = sin(2 * PI / len);
if (rev) wmy = -wmy;
for (int i = 0; i < n; i += len)
{
double wx = 1, wy = 0;
for (int j = 0; j < half; j++)
{
double cx = a[i + j], cy = b[i + j];
double dx = a[i + j + half], dy = b[i + j + half];
double ex = dx * wx - dy * wy, ey = dx * wy + dy * wx;
a[i + j] = cx + ex, b[i + j] = cy + ey;
a[i + j + half] = cx - ex, b[i + j + half] = cy - ey;
double wnx = wx * wmx - wy * wmy, wny = wx * wmy + wy * wmx;
wx = wnx, wy = wny;
}
}
}
if (rev)
{
for (int i = 0; i < n; i++)
a[i] /= n, b[i] /= n;
}
}
int solve(int a[],int na,int b[],int nb,int ans[])
{
int len = max(na, nb), ln;
for(ln=0; L(ln)<len; ++ln);
len=L(++ln);
for (int i = 0; i < len ; ++i)
{
if (i >= na) ax[i] = 0, ay[i] =0;
else ax[i] = a[i], ay[i] = 0;
}
fft(ax, ay, len, 0);
for (int i = 0; i < len; ++i)
{
if (i >= nb) bx[i] = 0, by[i] = 0;
else bx[i] = b[i], by[i] = 0;
}
fft(bx, by, len, 0);
for (int i = 0; i < len; ++i)
{
double cx = ax[i] * bx[i] - ay[i] * by[i];
double cy = ax[i] * by[i] + ay[i] * bx[i];
ax[i] = cx, ay[i] = cy;
}
fft(ax, ay, len, 1);
for (int i = 0; i < len; ++i)
ans[i] = (int)(ax[i] + 0.5);
return len;
}
std::string mul(std::string sa,std::string sb)
{
int l1,l2,l;
int i;
std::string ans;
memset(sum, 0, sizeof(sum));
l1 = sa.size();
l2 = sb.size();
for(i = 0; i < l1; i++)
x1[i] = sa[l1 - i - 1]-'0';
for(i = 0; i < l2; i++)
x2[i] = sb[l2-i-1]-'0';
l = solve(x1, l1, x2, l2, sum);
for(i = 0; i<l || sum[i] >= 10; i++) // 进位
{
sum[i + 1] += sum[i] / 10;
sum[i] %= 10;
}
l = i;
while(sum[l] <= 0 && l>0) l--; // 检索最高位
for(i = l; i >= 0; i--) ans+=sum[i] + '0'; // 倒序输出
return ans;
}
std::string BigInteger::multiply(std::string number1,std::string number2)
{
if(number1[0]!='-'&&number2[0]!='-'){
return mul(number1,number2);
}
else if(number1[0]=='-'&&number2[0]!='-'){
std::string absnumber1="";
for(size_t i=1;i<number1.size();i++)
{
absnumber1+=number1[i];
}
std::string result=multiply(number2,absnumber1);
return "-"+result;
}
else if(number1[0]!='-'&&number2[0]=='-'){
std::string absnumber2="";
for(size_t i=1;i<number2.size();i++)
{
absnumber2+=number2[i];
}
std::string result=multiply(number1,absnumber2);
return "-"+result;
}
else
{
std::string absnumber1="";
std::string absnumber2="";
for(size_t i=1;i<number1.size();i++)
{
absnumber1+=number1[i];
}
for(size_t i=1;i<number2.size();i++)
{
absnumber2+=number2[i];
}
return multiply(absnumber2,absnumber1);
}
}
const int L=2000;
int sub(int *a,int *b,int La,int Lb)
{
if(La<Lb) return -1;//如果a小于b,则返回-1
if(La==Lb)
{
for(int i=La-1;i>=0;i--)
if(a[i]>b[i]) break;
else if(a[i]<b[i]) return -1;//如果a小于b,则返回-1
}
for(int i=0;i<La;i++)//高精度减法
{
a[i]-=b[i];
if(a[i]<0) a[i]+=10,a[i+1]--;
}
for(int i=La-1;i>=0;i--)
if(a[i]) return i+1;//返回差的位数
return 0;//返回差的位数
}
std::string div(std::string n1,std::string n2,int nn)//n1,n2是字符串表示的被除数,除数,nn是选择返回商还是余数
{
std::string s,v;//s存商,v存余数
int a[L],b[L],r[L],La=n1.size(),Lb=n2.size(),i,tp=La;//a,b是整形数组表示被除数,除数,tp保存被除数的长度
std::fill(a,a+L,0);std::fill(b,b+L,0);std::fill(r,r+L,0);//数组元素都置为0
for(i=La-1;i>=0;i--) a[La-1-i]=n1[i]-'0';
for(i=Lb-1;i>=0;i--) b[Lb-1-i]=n2[i]-'0';
if(La<Lb || (La==Lb && n1<n2)) {
//cout<<0<<endl;
return n1;}//如果a<b,则商为0,余数为被除数
int t=La-Lb;//除被数和除数的位数之差
for(int i=La-1;i>=0;i--)//将除数扩大10^t倍
if(i>=t) b[i]=b[i-t];
else b[i]=0;
Lb=La;
for(int j=0;j<=t;j++)
{
int temp;
while((temp=sub(a,b+j,La,Lb-j))>=0)//如果被除数比除数大继续减
{
La=temp;
r[t-j]++;
}
}
for(i=0;i<L-10;i++) r[i+1]+=r[i]/10,r[i]%=10;//统一处理进位
while(!r[i]) i--;//将整形数组表示的商转化成字符串表示的
while(i>=0) s+=r[i--]+'0';
//cout<<s<<endl;
i=tp;
while(!a[i]) i--;//将整形数组表示的余数转化成字符串表示的</span>
while(i>=0) v+=a[i--]+'0';
if(v.empty()) v="0";
//cout<<v<<endl;
if(nn==1) return s;
if(nn==2) return v;
}
std::string BigInteger::divide(std::string number1,std::string number2,int floatpoint = 0)
{
if(number1[0]!='-'&&number2[0]!='-'){
return div(number1,number2,1);
}
else if(number1[0]=='-'&&number2[0]!='-'){
std::string absnumber1="";
for(size_t i=1;i<number1.size();i++)
{
absnumber1+=number1[i];
}
std::string result=divide(absnumber1,number2);
return "-"+result;
}
else if(number1[0]!='-'&&number2[0]=='-'){
std::string absnumber2="";
for(size_t i=1;i<number2.size();i++)
{
absnumber2+=number2[i];
}
std::string result=divide(number1,absnumber2);
return "-"+result;
}
else
{
std::string absnumber1="";
std::string absnumber2="";
for(size_t i=1;i<number1.size();i++)
{
absnumber1+=number1[i];
}
for(size_t i=1;i<number2.size();i++)
{
absnumber2+=number2[i];
}
return divide(absnumber1,absnumber2);
}
}
std::string BigInteger::mod(std::string number1,std::string number2)
{
if(compare(number1, number2) == 0)
{
return "0";
}
else if(number2[0]=='-')
{
return "error";
}
else{
return div(number1,number2,2);
std::string result=minus(number1, multiply(divide(number1, number2), number2));
if(compare("0",result)>0)
{
result=add(result,number2);
}
return result;
}
}
std::string BigInteger::gcd(std::string num1,std::string num2)
{
if (num1 == "0")
{
return num2;
}
if (num2 == "0")
{
return num1;
}
if (compare(num1,num2)==0)
{
std::string temp=num1;
num1=num2;
num2=temp;
}
std::string result = mod(num1,num2);
while(result != "0")
{
num1 = num2;
num2 = result;
result = mod(num1,num2);
}
return num2;
}
BigInteger BigInteger::divide2(std::string s)
{
BigInteger tmp;
int jin=0;
//ArrayList<Integer> list=new ArrayList<Integer>();
std::vector<int>list;
for(int i=0; i<s.length(); i++)
{
int cur=(s[i]-'0')+jin*10;
list.push_back(cur/2);
jin=cur%2;
}
std::string sb="";
int k=0;
while(k<list.size()&&list[k]==0)
{
k++;
}
if(k<list.size())
{
for(int i=k; i<list.size(); i++)
{
sb+=std::to_string(list[i]);
}
}
else
{
sb+='0';
}
tmp._num1=sb;
//res[1]=String.valueOf(jin);余数
// System.out.println(s+"/2="+res[0]);
// System.out.println(s+"%2="+res[1]);
return tmp;
}
std::string BigInteger::exgcd(std::string a,std::string b,std::string &x,std::string &y)
{
if( b == "0" ) {
x = "1";
y = "0";
return a;
}
else{
std::string x1,y1;
if(mod(a,b)=="error")
{
return "error";
}
std::string d = exgcd ( b ,mod(a,b),x1,y1);
x = y1;
std::string temp=divide(a,b);
std::string temp2=multiply(temp,y1);
y=minus(x1,temp2);
return d;
}
}
main.cpp
//优化了大数乘法和取模,15秒可以算512bit大数
#include<bits/stdc++.h>
#include<iostream>
//#include <python3.5m>
#include <Python.h>
#include <Python-ast.h>
#include "ClassBigInteger.h"
#include <string>
using namespace std;
#define MAXSIZE 2048
ostream& operator<<(ostream& out, const BigInteger& obj)
{
out <<obj.toString();
return out;
}
istream& operator>>(istream & in, BigInteger& b) //重载输入运算符
{
b.init();
std::string ch;
in>>ch;
b.setnum(ch);
return in;
}
BigInteger zero("0"),one("1");
BigInteger xx,yy;
int input[1024];
int output[2048];
int tentobin(std::string a)
{
memset(input,0,sizeof(input));
int shang,shang_sum,yu,k,j;
int len=a.length();
for(int i=0; i<len; i++)
{
input[i]=a[i]-'0';
//cout<<input[i]<<" ";
}
memset(output,0,sizeof(output));
shang_sum=1;
k=0;
shang=0;
while(shang_sum)
{
shang_sum=0;
//cout<<shang_sum;
for(int i=0; i<len; i++)
{
j=i+1;
shang=input[i]/2;
//cout<<i;
shang_sum+=shang;
yu=input[i]%2;
if(i==(len-1))output[k++]=yu;
else input[j]+=yu*10;
input[i]=shang;
}
}
return k;
}
void ExtendedEuclid(BigInteger a,BigInteger b)
{
if(b==zero)
{
xx=one,yy=zero;
return ;
}
ExtendedEuclid(b,a%b);
//cout<<xx<<" "<<yy<<" "<<a/b<<endl;
BigInteger tmp = xx;
xx = yy;
yy = tmp - ((a/b)*yy);
//cout<<xx<<" "<<yy<<" "<<tmp<<endl;
return ;
}
BigInteger encode(BigInteger m,BigInteger e,BigInteger n)
{
BigInteger t,ret("1"),two("2");
if(e<zero)
exit(-1);
if(e==zero)
return one;
if(e==one)
return m;
int len=tentobin(e.toString()),i=0;
while(i<len)
{
if(output[i]==1)
{
ret=ret*m%n;
}
m=m*m%n;
i++;
}
return ret%n;
}
BigInteger decode(BigInteger c,BigInteger d,BigInteger n)
{
BigInteger t,ret("1"),two("2");
if(d<zero)
exit(-1);
if(d==zero)
return one;
if(d==one)
return c;
int len=tentobin(d.toString()),i=0;
while(i<len)
{
if(output[i]==1)
{
ret = (ret*c)%n;
}
c = (c*c)%n;
i++;
}
return ret%n;
}
int main(int argc, char* argv[])
{
Py_Initialize(); //使用python之前,要调用Py_Initialize();这个函数进行初始化
PyRun_SimpleString("import sys");
PyRun_SimpleString("import random");
PyRun_SimpleString("sys.path.append('./')");
PyObject * pModule = NULL; //声明变量
PyObject * pFunc = NULL; //声明变量
pModule =PyImport_ImportModule("sjss"); //这里是要调用的Python文件名
if(pModule==NULL)
{
cout<<"Cant not open the file"<<endl;
return 0;
}
pFunc= PyObject_GetAttrString(pModule, "cxf"); //这里是要调用的函数名
PyObject *pReturn = NULL;
pReturn =PyEval_CallObject(pFunc, NULL); //调用函数
//PyEval_CallObject(pFunc, NULL); //调用函数,NULL表示参数为空
char* result1=NULL;
char* result2=NULL;
char* result3=NULL;
PyArg_Parse(pReturn, "s", &result1); //i表示转换成int型变量
//cout << result << endl;
pReturn =PyEval_CallObject(pFunc, NULL); //调用函数
PyArg_Parse(pReturn, "s", &result2); //i表示转换成int型变量
pReturn =PyEval_CallObject(pFunc, NULL); //调用函数
PyArg_Parse(pReturn, "s", &result3); //i表示转换成int型变量
std::string str1(result1);
std::string str2(result2);
std::string str3(result3);
//printf("%s\n",result1);
cout<<"the prime number P is:"<<endl;
cout<<str1<<endl;
cout<<"the prime number Q is:"<<endl;
cout<<str2<<endl;
cout<<"the prime number E is:"<<endl;
cout<<str3<<endl;
Py_Finalize(); //调用Py_Finalize,这个和Py_Initialize相对应的.
BigInteger p(str1);
BigInteger q(str2);
BigInteger n=p*q,r=(p-one)*(q-one);
cout<<"the number N=p*q is:"<<endl;
cout<<n<<endl;
cout<<"the number R=(p-1)*(q-1) is:"<<endl;
cout<<r<<endl;
//cout<<p.toString()<<" "<<q.toString()<<endl;
BigInteger e(str3);
ExtendedEuclid(e,r);
//cout<<xx.toString()<<" "<<yy.toString()<<endl;
cout<<"the number D=>(D*E=1 mod R) is:"<<endl;
BigInteger d=(xx%r+r)%r;
cout<<d.toString()<<endl;
BigInteger m("123456789");//明文
cout<<"the Plaintext is:"<<endl;
cout<<m<<endl;
BigInteger c=encode(m,e,n);
cout<<"the Ciphertext is:"<<endl;
cout<<c<<endl;
cout<<"the result is:"<<endl;
cout<<decode(c,d,n)<<endl;
//system("pause");
return 0;
}