一:说明: 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; }