C++和python混编,编译器为64位mingw。具体配置请参考网上相应技术博客。
代码为一个C++工程
ClassBigInteger.h
#ifndef CLASSBIGINT
#define CLASSBIGINT
#include <bits/stdc++.h>
class BigInteger
{
public:
BigInteger();
BigInteger(const BigInteger &);
BigInteger(std::string num1);
BigInteger(char num1);
~BigInteger();
private:
std::string _num1;
public:
//friend std::istream& operator>>(istream& in, const BigInteger& a);
// friend std::ostream& operator<<(ostream& ,const BigInteger& );
//静态方法
static int compare(std::string num1,std::string num2);//if num1>num2,return 1,else if num1=num2,return 0,else return -1;
static std::string add(std::string num1,std::string num2);//num1+num2
static std::string minus(std::string num1,std::string num2);//num1-num2
static std::string multiply(std::string num1,std::string num2);//num1*num2
static std::string divide(std::string num1,std::string num2,int floatpoint);//num1/num2
static std::string mod(std::string num1,std::string num2);//num1 mod num2
static std::string gcd(std::string num1,std::string num2);//gcd(num1,num2)
static std::string exgcd(std::string a,std::string b,std::string &x,std::string &y);//if gcd(a,b)=1,a*x+b*y=1,return gcd(a,b),x is inverse of a
//重载操作符
std::string toString() const;
void init();
void setnum(std::string );
BigInteger operator+(const BigInteger&);//+
BigInteger operator-(const BigInteger&);//-
BigInteger operator*(const BigInteger&);//*
BigInteger operator/(const BigInteger&);///
BigInteger operator%(const BigInteger&);//mod
bool operator==(const BigInteger&)const;//==
bool operator>(const BigInteger&)const;//>
bool operator<(const BigInteger&)const;//<
};
#endif CLASSBIGINT
ClassBigInteger.cpp
#include "ClassBigInteger.h"
#include<bits/stdc++.h>
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;
}
/*std::ostream& operator<<(ostream& out, const BigInteger& obj)
{
out <<obj.toString();
return out;
}*/
/*std::istream& operator<<(istream& in, const BigInteger& obj)
{
in>>obj.toString();
return in;
}*/
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);
}
}
std::string BigInteger::multiply(std::string number1,std::string number2)
{
if(number1[0]!='-'&&number2[0]!='-'){
int i, j;
int *iresult;
int length1 = number1.size();
int length2 = number2.size();
std::string result = "";
reverse(number1.begin(), number1.end());
reverse(number2.begin(), number2.end());
iresult = (int*)malloc(sizeof(int) * (length1 + length2 + 1));
memset(iresult, 0, sizeof(int) * (length1 + length2 + 1));
for(i = 0; i < length1; i++)
{
for(j = 0; j < length2; j++)
{
iresult[i+j] += ((number1[i] - 48) * (number2[j] - 48));
}
}
int carry = 0;
for(i = 0; i < length1 + length2; i++)
{
int value = iresult[i] + carry;
iresult[i] = value % 10;
carry = value / 10;
}
for(i = length1 + length2 - 1; i >= 0; i--)
{
if(iresult[i] != 0)
break;
}
for(; i >= 0; i--)
{
result = result + (char)(iresult[i]+48);
}
free(iresult);
if(result == "") 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=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);
}
}
std::string BigInteger::divide(std::string number1,std::string number2,int floatpoint = 0)
{
if(number1[0]!='-'&&number2[0]!='-'){
int i, j, pos;
std::string result = "";
std::string tempstr = "";
int length1 = number1.size();
int length2 = number2.size();
if((compare(number2, number1) > 0) && (floatpoint == 0))
{
return "0";
}
tempstr = number1.substr(0, length2);
pos = length2 - 1;
while(pos < length1)
{
int quotient = 0;
while(compare(tempstr, number2) >= 0)
{
quotient++;
tempstr = minus(tempstr, number2);
}
result = result + (char)(quotient + 48);
pos++;
if(pos < length1)
{
tempstr += number1[pos];
}
}
if(floatpoint > 0)
{
result += '.';
std::string stmp = "1";
int itmp = 0;
for(int k = 0; k < floatpoint; ++k)
{
stmp += '0';
if(compare(multiply(minus(number1, multiply(divide(number1, number2), number2)), stmp), number2) < 0)
{
result += '0';
++itmp;
}
}
std::string temp = divide(multiply(minus(number1, multiply(divide(number1, number2), number2)), stmp), number2);
if(temp[0] != '0') result += temp;
}
j = result.size();
for(i = 0; i < j; i++)
{
if(result[i] != '0') break;
}
result = result.substr(i, j);
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=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{
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;
}
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
#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 1024
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;
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;
while(e>zero)
{
if(e%two==one)
{
ret = (ret*m)%n;
}
m = (m*m)%n;
e=e/two;
}
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;
while(d>zero)
{
if(d%two==one)
{
ret = (ret*c)%n;
}
c = (c*c)%n;
d=d/two;
}
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;
}
大素数生成和检测用的python脚本
#!/usr/bin/python
#coding:utf-8
import random
import sys
def proBin(w): # w表示希望产生位数
list = []
list.append(1) #最高位定为1
for i in range(w - 2):
c = random.randint(0, 1)
list.append(c)
list.append(1)
ls2 = [str(j) for j in list]
ls3 = ''.join(ls2)
b = int(ls3[0])
for i2 in range(len(ls3) - 1):
b = b << 1
b = b + int(ls3[i2 + 1])
d = int(b)
return d
def X_n_mod_P(x, n, p): # x^n mod P 递归求法 (x*x)^(n/2) mod P = ((x*x)mod P)^(n/2) mod P
if n == 0:
return 1
res = X_n_mod_P((x * x) % p, n >> 1, p)
if n & 1 != 0:
res = (res * (x)) % p # x是较小数,x%p的结果就是本身
return res
def MillerRabin(a, p):
if X_n_mod_P(a, p - 1, p) == 1:
u = (p-1) >> 1
while (u & 1) == 0:
t = X_n_mod_P(a, u, p)
if t == 1:
u = u >> 1
else:
if t == p - 1:
return True
else:
return False
else:
t = X_n_mod_P(a, u, p)
if t == 1 or t == p - 1:
return True
else:
return False
else:
return False
def testMillerRabin(p, k): # k为测试次数,p为待测奇数
while k > 0:
a = random.randint(2, p - 1)
if not MillerRabin(a, p):
return False
k = k - 1
return True
def pro512(): # 产生512位素数
while 1:
d = proBin(512)
for i in range(50): # 伪素数附近50个奇数都没有真素数的话,重新再产生一个伪素数
u = testMillerRabin(d+2*(i), 5)
if u:
b = d + 2*(i)
break
else:
continue
if u:
return b
else:
continue
def cxf():
t1 = str(pro512())
#t2 = str(pro512())
#t3 = str(pro512())
#f1.open('test.txt','w')
#f1.write(t1)
#f1.close()
#print(t1)
#print(t2)
#print(t3)
return t1
#cxf()
# while 1:
# t1 = int(pro512())
# for k in range(4): #再产生一个512位的合数,判断乘积是否为1024位,
# t2 = proBin(512) - 1 #如果不是,再产生一个512位的合数,循环4次,如果不是,产生一个新的512质数
# t = t1*t2
# h = len(bin(t)) - 2
# if h == 1024:
# break
# else:
# continue
# if not h == 1024:
# continue
# else:
# for i in range(50): #循环五十次判断判断t3是否为质数,如果不是t2周围去尝试
# t2 = t2 + 2*i
# t3 = t1*t2 + 1
# u = testMillerRabin(t3, 5)
# if u:
# break
# else:
# continue
# if u:
# break
# else:
# continue
# print('小质数t1(2) =', bin(t1)[2:])
# print('小质数t1(10) =',t1)
# print('倍数t2(2) =', bin(t2)[2:])
# print('倍数t2(10) =',t2)
# print('大质数t3(2) =', bin(t3)[2:])
# print('大质数t3(10) =',t3)
//优化了大数乘法和取模,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;
}
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保存被除数的长度
fill(a,a+L,0);fill(b,b+L,0);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;
}
#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;
}
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 ;
}
std::string 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;
std::string ret="1",mm=m.toString(),nn=n.toString();
while(i<len)
{
if(output[i]==1)
{
//ret = (ret*m)%n;
//cout<<ret<<endl;
ret=mul(ret,mm);
ret=div(ret,nn,2);
}
mm=mul(mm,mm);
mm=div(mm,nn,2);
//m = (m*m)%n;
//e=e/two;
//e.divide2(e.toString());
i++;
}
ret=div(ret,nn,2);
return ret;
}
std::string 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;
//cout<<ret<<endl;
}
c = (c*c)%n;
//e=e/two;
//e.divide2(e.toString());
i++;
}
return ret%n;*/
int len=tentobin(d.toString()),i=0;
std::string ret="1",cc=c.toString(),nn=n.toString();
while(i<len)
{
if(output[i]==1)
{
//ret = (ret*m)%n;
//cout<<ret<<endl;
ret=mul(ret,cc);
ret=div(ret,nn,2);
}
cc=mul(cc,cc);
cc=div(cc,nn,2);
//m = (m*m)%n;
//e=e/two;
//e.divide2(e.toString());
i++;
}
ret=div(ret,nn,2);
return ret;
}
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 a("5"),b("3"),tt("7");
//cout<<qmul(a,b,tt)<<endl;
std::string c=encode(m,e,n);
cout<<"the Ciphertext is:"<<endl;
cout<<c<<endl;
BigInteger cip(c);
cout<<"the result is:"<<endl;
cout<<decode(cip,d,n)<<endl;
//system("pause");
//BigInteger two("2");
//cout<<n/two<<endl;
return 0;
}
最后,如果用16进制加解密,我的最优能到6秒,代码也不长,改天贴一篇新的。。。。