poj2447 RSA公钥加密破译

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define MAXN 10
#define C 16381
long long min;

long long multi(long long a, long long b, long long n){
long long tmp = a % n, s = 0;
while(b){
if(b & 1) s = (s + tmp) % n;
tmp = (tmp + tmp) % n;
b >>= 1;
}
return s;
}

long long Pow(long long a, long long b, long long n){
long long tmp = a % n, s = 1;
while(b){
if(b & 1) s = multi(s, tmp, n);
tmp = multi(tmp, tmp, n);
b >>= 1;
}
return s;
}

int witness(long long a, long long n){
long long u = n - 1, t = 0, i, x, y;
while(!(u & 1)) u >>= 1, t ++;
x = Pow(a, u, n);
for(i = 1; i <= t; i ++){
y = multi(x, x, n);
if(y == 1 && x != 1 && x != n -1) return 1;
x = y;
}
if(x != 1) return 1;
return 0;
}

int test(long long n){
long long a;
int i;
if(n == 2) return 1;
if(n < 2 || !(n & 1)) return 0;
srand((long long)time(0));
for(i = 0; i < MAXN; i ++){
a = ((long long) rand()) % (n - 2) + 2;
if(witness(a, n)) return 0;
}
return 1;
}

long long gcd(long long a, long long b){
return b ? gcd(b, a % b) : a;
}

long long pollard_rho(long long n, long long c){
long long x, y, d, i = 1, k = 2;
srand((long long)time(0));
x = ((long long) rand()) % (n - 1) + 1;
y = x;
while(1){
i ++;
x = (multi(x, x, n) + c) % n;
d = gcd(y - x + n, n);
if(d != 1 && d != n) return d;
if(y == x) return n;
if(i == k) y = x, k <<= 1;
}
}

void find(long long n, long long c){
long long r;
if(n <= 1) return;
if(test(n)){
if(min > n) min = n;
return;
}
r = pollard_rho(n, c--);
find(r, c);
find(n / r, c);
}

int main(){
int t; 
long long i, s, n;
scanf("%d", &t);
while(t --){
scanf("%lld", &n);
if(test(n)){
printf("Prime\n");
continue;
}
min = n;
find(n, C);
printf("%lld\n", min);
}
return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值