C#版本 拉賓米勒算法,這是目前最快的算法,沒有之一,就是最快,9位的素數,也是秒出結果。
bool RabbinMillerTest(long n)
{
if (n < 2)
{ // 小於2的數即不是合數也不是素數
return false;
}
int[] aPrimeList = {
2, 3, 5, 7, 11, 17, 19, 23, 29, 31, 41,
43, 47, 53, 59, 67, 71, 73, 79, 83, 89, 97 };
int nPrimeListSize = aPrimeList.Count();//求素數表元素個數
for (int i = 0; i < nPrimeListSize; ++i)
{// 按照素數表中的數對當前素數進行判斷
if (n / 2 + 1 <= aPrimeList[i])
{// 如果已經小於當前素數表的數,則一定是素數
return true;
}
if (0 == n % aPrimeList[i])
{// 餘數爲0則說明一定不是素數
return false;
}
}
// 找到r和m,使得n = 2^r * m + 1;
long r = 0, m = n - 1; // ( n - 1 ) 一定是合數
while (0 == (m & 1))
{
m >>= 1; // 右移一位
r++; // 統計右移的次數
}
int nTestCnt = 10000; // 表示進行測試的次數
Random randkey = new Random(57);
for (int i = 0; i < nTestCnt; ++i)
{ // 利用隨機數進行測試,
int a = aPrimeList[randkey.Next(0, nPrimeListSize)];
if (1 != Montgomery(a, m, n))
{
int j = 0;
int e = 1;
for (; j < r; ++j)
{
if (n - 1 == Montgomery(a, m * e, n))
{
break;
}
e <<= 1;
}
if (j == r)
{
return false;
}
}
}
return true;
}
long Montgomery(long n, long p, long m)
{ //快速計算(n^e)%m的值
long k = 1;
n %= m;
while (p != 1)
{
if (0 != (p & 1)) k = (k * n) % m;
n = (n * n) % m;
p >>= 1;
}
return (n * k) % m;
}