Miller-Rabin素數測試學習筆記


  好幾天前看了算導上的Miller-Rabin素數測試算法,今天正好總結一下,寫寫筆記。

  說Miller-Rabin測試以前先說兩個比較高效的求a*b% n 和 ab %n 的函數,這里都是用到二進制思想,將b拆分成二進制,然后與a相加(相乘)

// a * b % n
//例如: b = 1011101那么a * b mod n = (a * 1000000 mod n + a * 10000 mod n + a * 1000 mod n + a * 100 mod n + a * 1 mod n) mod n

ll mod_mul(ll a, ll b, ll n) {
ll res = 0;
while(b) {
if(b&1) res = (res + a) % n;
a = (a + a) % n;
b >>= 1;
}
return res;
}

 

//a^b % n
//同理
ll mod_exp(ll a, ll b, ll n) {
ll res = 1;
while(b) {
if(b&1) res = mod_mul(res, a, n);
a = mod_mul(a, a, n);
b >>= 1;
}
return res;
}

下面開始說Miller-Rabin測試:

  費馬小定理:對於素數p和任意整數a,有ap ≡ a(mod p)(同余)。反過來,滿足ap ≡ a(mod p),p也幾乎一定是素數。

  偽素數:如果n是一個正整數,如果存在和n互素的正整數a滿足 an-1 ≡ 1(mod n),我們說n是基於a的偽素數。如果一個數是偽素數,那么它幾乎肯定是素數。

  Miller-Rabin測試:不斷選取不超過n-1的基b(s次),計算是否每次都有bn-1 ≡ 1(mod n),若每次都成立則n是素數,否則為合數。 

偽代碼:

Function Miller-Rabin (n : longint) :boolean;
begin
for i := 1 to s do
begin
a := random(n - 2) + 2;
if mod_exp(a, n-1, n) <> 1 then return false;
end;
return true;
end;


注意,MIller-Rabin測試是概率型的,不是確定型的,不過由於多次運行后出錯的概率非常小,所以實際應用還是可行的。(一次Miller-Rabin測試其成功的概率為3/4)

 

前邊說的偽代碼實現很簡短,下面還有一個定理,能提高Miller測試的效率:

二次探測定理

  如果p是奇素數,則 x2 ≡ 1(mod p)的解為 x = 1 || x = p - 1(mod p);

可以利用二次探測定理在實現Miller-Rabin上添加一些細節,具體實現如下:

bool miller_rabin(ll n) {
if(n == 2 || n == 3 || n == 5 || n == 7 || n == 11) return true;
if(n == 1 || !(n%2) || !(n%3) || !(n%5) || !(n%7) || !(n%11)) return false;

ll x, pre, u;
int i, j, k = 0;
u = n - 1; //要求x^u % n

while(!(u&1)) { //如果u為偶數則u右移,用k記錄移位數
k++; u >>= 1;
}

srand((ll)time(0));
for(i = 0; i < S; ++i) { //進行S次測試
x = rand()%(n-2) + 2; //在[2, n)中取隨機數
if((x%n) == 0) continue;

x = mod_exp(x, u, n); //先計算(x^u) % n,
pre = x;
for(j = 0; j < k; ++j) { //把移位減掉的量補上,並在這地方加上二次探測
x = mod_mul(x, x, n);
if(x == 1 && pre != 1 && pre != n-1) return false; //二次探測定理,這里如果x = 1則pre 必須等於 1,或則 n-1否則可以判斷不是素數
pre = x;
}
if(x != 1) return false; //費馬小定理
}
return true;
}

 

  前邊這個算法經過測試還是比較靠譜的,可以用作模板。本菜也找過其他模板,可是有的居然把9測成素數,汗 -_-!


AC_Von 原創,轉載請注明出處:http://www.cnblogs.com/vongang/archive/2012/03/15/2398626.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM