一:说明: Rabin-Miller算法是用来测试一个数是否是一个素数的,以下是它的设计与实现。 二:原理 1:费马小定理 if n is prime and (a,n) equals one ,then a^(n-1) = 1 (mod n) 2:费马小定理只是个必要条件,符合费马小定理而非素数的数叫做Carmichael. 3:前3个Carmichael数是561,1105,1729,Carmichael数是非常少的。在1~100000000范围内的整数中,只有255个Carmichael数。为此又有二次探测定理,以确保该数为素数。 4:二次探测定理 如果p是一个素数,0<x<p,则方程x^2≡1(mod p)的解为x=1,p-1 三:算法 根据以上两个定理,如到Miller-Rabin算法的一般步骤: 0、先计算出m、j,使得n-1=m*2^j,其中m是正奇数,j是非负整数 1、随机取一个b,2<=b 2、计算v=b^m mod n 3、如果v==1,通过测试,返回 4、令i=1 5、如果v=n-1,通过测试,返回 6、如果i==j,非素数,结束 7、v=v^2 mod n,i=i+1 8、循环到5
四:C语言实现:
#include <stdio.h>
#include <math.h>
int Prime(long long num);
int Witness(int n, long long num);
int main()
{
int n;
while(1)
{
printf("Please enter a number: ");
scanf("%d", &n);
if(0 == n)
break;
if( Prime(n) )
printf("Yes, it is a prime number.\n");
else
printf("No, it isn't a prime number.\n");
}
return 0;
}
//我们要判断n是不是素数,首先我们必须保证n是个奇数
int Prime(long long num)
{
int arr[3] = {19,71,97};
int i;
if(2 == num)
return 1;
if(1==num || 0==num%2)
return 0;
for(i=0;i<3;i++)
{
if( Witness(arr[i], num) )
return 0;
}
return 1;
}
int Witness(int a,long long n)
{
long long j, m, x0, x1, b, i;
m = n-1;
j = 0;
while(m%2 == 0)
{
m /= 2;
j++;
}
b = a;
x0 = 1;
while(m)
{
if(m%2)
x0 = x0 * b % n;
m /= 2;
b = b * b % n;
}
for(i=0;i<j;i++)
{
x1 = x0 * x0 % n;
if(x1==1 && x0!=1 && x0!=n-1)
return 1;
x0 = x1;
}
if(x0 != 1)
return 1;
return 0;
}