MR素性检测算法

来源:互联网 发布:阿里云国际版价格 2017 编辑:程序博客网 时间:2024/05/17 06:07

素数是除了自身和1以外,没有其它素数因子的自然数。自从欧几里得证明了有无穷个素数以后,人们就企图寻找一个可以构造所有素数的公式,寻找判定一个自然数是不是素数的方法。因为素数的地位非常重要。

鉴别一个自然数是素数还是合数,这个问题在中世纪就引起人们注意,当时人们试图寻找质数公式,到了高斯时代,基本上确认了简单的质数公式是不存在的,因此,高斯认为对素性判定是一个相当困难的问题。从此以后,这个问题吸引了大批数学家。 素性判断算法可分为两大类,确定性算法及随机算法。前者可给出确定的结果但通常较慢,后者则反之。

这里主要讲米勒拉宾算法,最后提供c++实现代码。

要测试 N 是否为素数,首先将N-1 分解为2^s d。在每次测试开始时,先随机选一个 介于[1, N-1]的整数a,之后如果对所有的r \in [0, s-1],若a^d \mod N \neq 1a^{2^{r}d} \mod N \neq -1,则 N 是合数。否则,N3/4 的概率为素数。

Miller-Rabin算法随机生成底数a,进行多次调用函数进行测试,Miller-Rabin检测也存在伪素数的问题,但是与费马检测不同,MR检测的正确概率不依赖被检测数p,而仅依赖于检测次数。已经证明,如果一个数p为合数,那么Miller-Rabin检测的证据数量不少于比其小的正整数的3/4,换言之,k次检测后得到错误结果的概率为(1/4)^k。我们在实际应用中一般可以测试15~20次。

#include <iostream>#include <cmath>using namespace std;long long qpow(int a,int b,int r)//快速幂{    long long ans=1,buff=a;    while(b)    {        if(b&1)ans=(ans*buff)%r;        buff=(buff*buff)%r;        b>>=1;    }    return ans;}bool Miller_Rabbin(int n,int a)//米勒拉宾素数测试{    int r=0,s=n-1,j;    if(!(n%a))        return false;    while(!(s&1)){        s>>=1;        r++;    }    long long k=qpow(a,s,n);    if(k==1)        return true;    for(j=0;j<r;j++,k=k*k%n)        if(k==n-1)            return true;    return false;}bool IsPrime(int n)//判断是否是素数{    int tab[]={2,3,5,7};    for(int i=0;i<4;i++)    {        if(n==tab[i])            return true;        if(!Miller_Rabbin(n,tab[i]))            return false;    }    return true;}int main(){    long long n;    while(1)    {       cin >> n;    cout << IsPrime(n)<< endl;    }    return 0;}





0 0
原创粉丝点击