思路:
1.先暴力求出p, q
2.求逆元得到私钥e,注意:快速幂求逆元可能会越界,通过扩展欧几里得求。
3.用快速幂+快速乘。求(a^b) mod n
#include <bits/stdc++.h>
using namespace std;
long long n = 1001733993063167141LL;
long long fast_cheng(long long a, long long b, long long n){ //求(a*b) mod n
long long ans = 0;
while (b){
if (b & 1) ans = (ans + a) % n;
a = (a * 2) % n;
b >>= 1;
}
return ans;
}
long long fast_mi(long long a, long long b, long long n){
long long ans = 1;
while (b != 0){
//if (b & 1) ans = (ans * a) % n; //用快速乘
if (b & 1) ans = fast_cheng(ans, a, n);
//a = (a * a) % n; //用快速乘
a = fast_cheng(a, a, n);
b >>= 1;
}
return ans;
}
long long exgcd(long long a, long long b, long long &x1, long long &y1){
if (b == 0){
x1 = 1;
y1 = 0;
return a;
}
long long gcd = exgcd(b, a % b, x1, y1);
long long tmp = x1;
x1 = y1;
y1 = tmp - a / b * y1;
return gcd;
}
int main(){
long long d = 212353;
long long C = 20190324;
long long p = 891234941, q = 1123984201; //891234941 1123984201
long long e;
//质因子分解出p q,暴力
// for (long long i = 2; i <= (long long)sqrt(1.0 * n); ++i){
// if (n % i == 0){
// p = i;
// q = n / p;
// cout << p << " " << q << endl;
// }
// }
//通过快速幂求逆元e,越界!
//cout << fast(d, (p - 1) * (q - 1) -2) << endl;
//e = fast(d, (p - 1) * (q - 1) -2);
//cout << ((p - 1) * (q - 1)) << endl;
//通过扩展欧几里得求逆元
//long long x1, y1;
//exgcd(d, (p - 1) * (q - 1), x1, y1);
//e = (x1 % ((p - 1) * (q - 1)) + ((p - 1) * (q - 1))) % ((p - 1) * (q - 1));
//计算C^e mod n 快速幂+快速乘
e = 823816093931522017;
cout << fast_mi(C, e, n) << endl;
//输出密文:579706994112328949
cout << fast_mi(579706994112328949LL, 212353, n) << endl; //验证明文正确
return 0;
}