Rabin -Miller算法是典型的验证一个数字是否为素数的方法。判断素数的方法是Rabin-Miller概率测试,那么他具体的流程是什么呢。假设我们要判断n是不是素数,首先我们必须保证n 是个奇数,那么我们就可以把n 表示为 n = (2^r)*s+1,注意s 也必须是一个奇数。然后我们就要选择一个随机的整数a (1<=a<=n-1),接下来我们就是要判断 a^s=1 (mod n) 或a^((2^j)*s)= -1(mod n)(0<=j如果任意一式成立,我们就说n通过了测试,但是有可能不是素数也能通过测试。所以我们通常要做多次这样的测试,以确保我们得到的是一个素数。(DDS的标准是要经过50次测试)
采用Rabin-Miller算法进行验算
首先选择一个代测的随机数p,计算b,b是2整除p-1的次数。然后计算m,使得n=1+(2^b)m。
(1) 选择一个小于p的随机数a。
(2) 设j=0且z=a^m mod p
(3) 如果z=1或z=p-1,那麽p通过测试,可能使素数
(4) 如果j>0且z=1, 那麽p不是素数
(5) 设j=j+1。如果j且z<>p-1,设z=z^2 mod p,然后回到(4)。如果z=p-1,那麽p通过测试,可能为素数。
(6) 如果j=b 且z<>p-1,不是素数
- #include<iostream.h>
- #include<time.h>
- #include<stdlib.h>
- //随机数产生器
- //产生m~n之间的一个随机数
- unsigned long random(unsigned long m,unsigned long n)
- {
- srand((unsigned long)time(NULL));
- return(unsigned long)(m+rand()%n);
- }
- //模幂函数
- //返回X^YmodN
- long PowMod(long x,long y,long n)
- {
- long s,t,u;
- s=1;t=x;u=y;
- while(u){
- if(u&1)s=(s*t)%n;
- u>>=1;
- t=(t*t)%n;
- }
- return s;
- }
- //Rabin-Miller素数测试,通过测试返回1,否则返回0。
- //n是待测素数。
- //注意:通过测试并不一定就是素数,非素数通过测试的概率是1/4
- int RabinMillerKnl(unsigned long n)
- {
- unsigned long b,m,j,v,i;
- //先计算出m、j,使得n-1=m*2^j,其中m是正奇数,j是非负整数
- m=n-1;
- j=0;
- while(!(m&1))
- {
- ++j;
- m>>=1;
- }
- //随机取一个b,2<=b<n-1
- b=random(2,m);
- //计算v=b^mmodn
- v=PowMod(b,m,n);
- //如果v==1,通过测试
- if(v==1)
- {
- return 1;
- }
- i=1;
- //如果v=n-1,通过测试
- while(v!=n-1)
- {
- //如果i==l,非素数,结束
- if(i==j)
- {
- return 0;
- }
- //v=v^2modn,i=i+1
- v=PowMod(v,2,n);
- i++;
- }
- return 1;
- }
- intmain()
- {
- unsigned long p;
- int count=0;
- cout<<"请输入一个数字"<<endl;
- cin>>p;
- for(int temp=0;temp<5;temp++)
- {
- if(RabinMillerKnl(p))
- {
- count++;
- }
- else
- break;
- }
- if(count==5)
- cout<<"一共通过5次测试,是素数!"<<endl;
- else
- cout<<"不是素数"<<endl;
- return 0;
- }
本文介绍了Rabin-Miller检验法用于判定大数是否为素数的流程。该算法首先将大数表示为n = (2^r) * s + 1的形式,然后选择随机整数a进行测试。如果满足特定条件,则认为可能是素数。通过多次测试增加正确性,代码示例展示了如何应用Rabin-Miller算法进行素数检验。
292

被折叠的 条评论
为什么被折叠?



