|
|
发表于 2011-6-9 17:58:16
|
显示全部楼层
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,不是素数
- 01.#include<iostream.h>
- 02.#include<time.h>
- 03.#include<stdlib.h>
- 04.
- 05.//随机数产生器
- 06.//产生m~n之间的一个随机数
- 07.unsigned long random(unsigned long m,unsigned long n)
- 08.{
- 09. srand((unsigned long)time(NULL));
- 10. return(unsigned long)(m+rand()%n);
- 11.}
- 12.//模幂函数
- 13.//返回X^YmodN
- 14.long PowMod(long x,long y,long n)
- 15.{
- 16. long s,t,u;
- 17.
- 18. s=1;t=x;u=y;
- 19. while(u){
- 20. if(u&1)s=(s*t)%n;
- 21. u>>=1;
- 22. t=(t*t)%n;
- 23. }
- 24. return s;
- 25.}
- 26.
- 27.
- 28.//Rabin-Miller素数测试,通过测试返回1,否则返回0。
- 29.//n是待测素数。
- 30.//注意:通过测试并不一定就是素数,非素数通过测试的概率是1/4
- 31.
- 32.int RabinMillerKnl(unsigned long n)
- 33.{
- 34. unsigned long b,m,j,v,i;
- 35. //先计算出m、j,使得n-1=m*2^j,其中m是正奇数,j是非负整数
- 36. m=n-1;
- 37. j=0;
- 38. while(!(m&1))
- 39. {
- 40. ++j;
- 41. m>>=1;
- 42. }
- 43. //随机取一个b,2<=b<n-1
- 44. b=random(2,m);
- 45. //计算v=b^mmodn
- 46. v=PowMod(b,m,n);
- 47. //如果v==1,通过测试
- 48. if(v==1)
- 49. {
- 50. return 1;
- 51. }
- 52.
- 53. i=1;
- 54. //如果v=n-1,通过测试
- 55. while(v!=n-1)
- 56. {
- 57. //如果i==l,非素数,结束
- 58. if(i==j)
- 59. {
- 60. return 0;
- 61. }
- 62. //v=v^2modn,i=i+1
- 63. v=PowMod(v,2,n);
- 64. i++;
- 65. }
- 66. return 1;
- 67.}
- 68.intmain()
- 69.{
- 70. unsigned long p;
- 71. int count=0;
- 72. cout<<"请输入一个数字"<<endl;
- 73. cin>>p;
- 74. for(int temp=0;temp<5;temp++)
- 75. {
- 76. if(RabinMillerKnl(p))
- 77. {
- 78. count++;
- 79. }
- 80. else
- 81. break;
- 82.
- 83. }
- 84.
- 85. if(count==5)
- 86. cout<<"一共通过5次测试,是素数!"<<endl;
- 87. else
- 88. cout<<"不是素数"<<endl;
- 89. return 0;
- 90.}
复制代码
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/aichaoguy/archive/2010/12/04/6054915.aspx
|
|