By Wen Jian
【背景】
数论学家利用费马小定理研究出了多种素数测试办法,Miller-Rabbin 素数测试算法是其中较快的一种。
【步骤】
(1)计算奇数M,使得N=2^r * M + 1;
(2)选择随机数A<N;
(3)对于任意i<r,若A^(2^i*M) mod N = N - 1,则N通过随机数A的测试;
(4)或者,若A^M mod N = 1,则N通过随机数A的测试;
(5)让A取不同的值对N进行行多次测试(一般要求5~10次,有较高要求的话可以进行20~30次),若全部通过则判定N为素数;
【概率】
若N通过一次测试,则N不是素数的概率为25%;
若N通过 t 次测试,则N不是素数的概率为1/( 4 ^ t );
事实上,当 t = 5 时,N不是素数的概率已为1/128,已经大于99.99%。
在实际运用中,可首先用300~500个小素数对N进行测试,以提高测试通过的概率与算法的速度。在随机生成的素数中,选取的随机数最好让 r = 0,则可以省去步骤(3)的操作,进一步减少判定时间。
【代码】
#include<cstdlib>
#include<ctime>
#include<cstdio>
using namespace std;
const int count=10;
int modular_exp(int a,int m,int n)
{
if(m==0)
return 1;
if(m==1)
return (a%n);
long long w=modular_exp(a,m/2,n);
w=w*w%n;
if(m&1)
w=w*a%n;
return w;
}
bool Miller_Rabin(int n)
{
if(n==2)
return true;
for(int i=0;i<count;i++)
{
int a=rand()%(n-2)+2;
if(modular_exp(a,n,n)!=a)
return false;
}
return true;
}
int main()
{
srand(time(NULL));
int n;
scanf("%d",&n);
if(Miller_Rabin(n))
printf("Probably a prime.");
else
printf("A composite.");
printf("\n");
return 0;
}
Coding by SinGuLaRiTy
Time : 2017-02-07