您的位置:首页 > 其它

菜鸟系列——pollard_rho分解质因子

2015-08-18 15:43 337 查看

菜鸟就要老老实实重新学起:

pollard_rho分解质因子:

利用miller-rabin和pollard_rho算法进行大素数判断和素因子分解。

模版:

long long factor[1000];//质因数分解结果(刚返回时是无序的)
int sum;//质因数的个数。数组小标从0开始

#define T 100//随机算法判定次数,N越大,判错概率越小

long long modMul(long long a,long long b,long long n)
{
long long res = 0;
while(b)
{
if(b&1)    res = (res + a) % n;
a = (a + a) % n;
b >>= 1;
}
return res;
}
long long modExp(long long x,long long k,long long mod)
{
long long ans = 1;
while(k)
{
if(k & 1) ans = modMul(ans, x, mod);
x = modMul(x, x, mod);
k >>= 1;
}
return ans;
}
bool millerRabin(long long n)
{
if(n == 2 || n == 3 || n == 5 || n == 7 || n == 11)    return true;
if(n == 1 || !(n%2) || !(n%3) || !(n%5) || !(n%7) || !(n%11))    return false;

long long x, pre, u;
int i, j, k = 0;
u = n - 1;

while(!(u&1))
{
k++;
u >>= 1;
}

srand((long long)time(0));
for(i = 0; i < T; ++i)
{
x = rand()%(n-2) + 2;
if((x%n) == 0)
continue;
x = modExp(x, u, n);
pre = x;
for(j = 0; j < k; ++j)
{
x = modMul(x,x,n);
//二次探测判断
if(x == 1 && pre != 1 && pre != n-1)
return false;
pre = x;
}
//费小判断
if(x != 1)
return false;
}
return true;
}

long long gcd(long long a,long long b)
{
if(a==0)return 1;
if(a<0) return gcd(-a,b);
while(b)
{
long long t=a%b;
a=b;
b=t;
}
return a;
}
long long pollardRho(long long x,long long c)
{
long long i=1,k=2;
long long x0=rand()%x;
long long y=x0;
while(1)
{
i++;
x0=(modMul(x0,x0,x)+c)%x;
long long d=gcd(y-x0,x);
if(d!=1&&d!=x) return d;
if(y==x0) return x;
if(i==k){y=x0;k+=k;}
}
}
//对n进行素因子分解
void findFac(long long x)
{
srand((long long)time(0));
if(millerRabin(x))//素数
{
factor[sum++]=x;
return;
}
long long p=x;
while(p>=x)
p=pollardRho(p,rand()%(x-1)+1);
findFac(p);
findFac(x/p);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: