Miller__Rabin素数测试

来源:互联网 发布:钻石儿童玩具淘宝网 编辑:程序博客网 时间:2024/06/05 20:55

                                                  Miller__Rabin素数测试

米勒拉宾素数测试 
          

测试大素数的原基于   
                如果  n 是素数 且与a 互质 那么则有  a ^(n -1)  = 1 (mod n)  

这个和费马小定理    a^n  = a(mod n) 差不多
 
1、因此首先可以进行快速幂取模函数  qpow()  
2 、先将y(y = n-1) 的偶数倍先将其右边为0 的部分去掉 ,然后进行快速幂求模
3、 这里求出的结果可能不会是1  因此将n 适当的放大  x= (x*x)%n  y 也同时扩大1倍 这里的目的其实就是为了在求快速幂当中取模 过程中模出现为1 或者n-1的情况
4、 最后的结果如过 x = n - 1或者 y 是奇数的话,说明已经通过了测试

在32位的数字中, 经验显示 只要是以 2 、7 、61 为底, n 为幂的数,通过了测试,那么这个数就是素数



代码:
#include<iostream>using namespace std;int qpow(int a, int b , int M){    //快速幂取模    int ans = 1;    while(b)    {        if(b&1)        {            ans*= a;            ans %= M;        }        a*= a ;        a%= M;        b>>= 1;    }    return ans;}bool Miller_Rabin(int x , int n){    //这里主要是测试n 是不是素数    int y = n -1;    while(!(y&1)) y>>= 1 ;//去掉y 右边全是0的部分    x = qpow(x, y, n);  //快速幂取模x 为底 y 为幂 n 为模    while(y < n-1 && x != 1&& x != n-1)    {        x = (x*x)%n ;        y <<= 1;    }    //最后的结果是要么x = n -1 或者是 为奇数    return x == n-1 || (y&1) == 1;}int isPrime32(int n ){    //在32 位下, 如果能以2 7 61 为底通过Miller_Rabin测试那么就是素数了    if(n == 2 || n == 7 || n == 61) return 1;    if(n == 1 || (n&1) == 0) return 0 ; //如果n为1 或者说是偶数 那么一定不是合数    return  Miller_Rabin(2, n) && Miller_Rabin(7,n) && Miller_Rabin(61, n);}int main(){    int n ;    while(cin >>n)    {        if(isPrime32(n))        {            cout<<"是素数"<<endl;        }        else        {            cout<<"不是素数"<<endl;        }    }    return 0 ;}


0 0
原创粉丝点击