定义:令 n - 1 = ( 2^s ) * d,其中 s 是非负整数,d 是正奇数。若 a^d =1 ( mod n ) 或 a^((2^r)*d) = -1 ( mod n ),0 <= r <= s - 1,则称 n 通过以 a 为基的 R-M 测试。
定理:若 n 为奇合数,则 n 通过以 a 为基的 R-M 测试的数目最多为 ( n - 1 ) / 4, 1 <= a <= n - 1
这便是 Miller - Rabin 素数测试的基本思想。
若 p 为素数,且 0 < x < p,则方程 x * x = 1 ( mod p ) 的解为 x = 1, p - 1 ( mod p )。
事实上 x * x = 1 ( mod p ) 等价于 x * x - 1 = 0 ( mod p ),则 ( x - 1 )( x + 1 ) = 0 ( mod p )。故 p 须整除 x - 1 或 x + 1,由 p 为素数且 0 < x < p,推出 x = 1 ( mod p ) 或 x = p - 1 ( mod p )。
若 p 为素数,且 0 < a < p,则 a^(p-1) = 1 ( mod p )。
M - R 素数测试的思想最重要的就是如何分析和理解“二次探测定理”,或者称为“平方探测法”。整个 M - R 的测试过程就是围绕着该定理展开的。
下面给出 M - R 测试的伪代码:
Input: n > 2, an odd integer to be tested for primality; k, a parameter that determines the accuracy of the test Output: composite if n is composite, otherwise probably prime write n − 1 as 2^s·d with d odd by factoring powers of 2 from n − 1 LOOP: repeat k times: pick a randomly in the range [2, n − 2] x ← a^d mod n if x = 1 or x = n − 1 then do next LOOP for r = 1 .. s − 1 x ← x^2 mod n if x = 1 then return composite if x = n − 1 then do next LOOP return composite return probably prime
只要理解了“平方探测法”,那么 M - R 的思想和正确性就很好理解了。
可操作的 M - R 测试素数法并非对 0 < a < p 进行全遍历,而是采用 a = Random [ 2, p - 2 ] 的方式。因此存在误判为 Carmichael 数的情况。
经我在 VC 10 平台,采用 __rdtsc() 取随机数的方式:
三次 M - R 循环测试,误报率不到“千万分之二”。
两次 M - R 循环测试,误报率不到“百万分之一”。
效率上,VC 10 RELEASE 模式下,采用三次循环 M - R,测试第 19999 个素数 224729 时,快除法快
而测试第 20000 个素数 224737 时,M - R 法快
因此,为保证最高效,测试大数 n 时,可以先对其使用前 19999 个素数进行快除法排除,而后再使用 M - R 测试。
生成和测试N位大素数的方法
http://blog.csdn.net/hikaliv/archive/2009/06/03/4240167.aspx
有志于学,虽草庐中应可知天下事!