首先說下Rabin-Miller檢測素數的演算法,
演算法描述網上很多,由於經過多次轉載所以都有錯誤存在,下面是我綜合多個修改後得到的
//Rabin-Miller
//這是個很容易且廣泛使用的簡單演算法,它基於Gary Miller的部分象法,有Michael Rabin發展。事實上,這是在NIST的DSS建議中推薦的演算法的一個簡化版。
//首先選擇一個代測的隨機數p,計算b,b是2整除p-1的次數。然後計算m,使得p=1+(2^b)m。
//(1) 選擇一個小於p的隨機數a,且大於2。
//(2) 設j=0且z=a^m mod p
//(3) 如果z=1或z=p-1,那麽p通過測試,可能使素數
//(4) 如果j>0且z=1, 那麽p不是素數
//(5) 設j=j+1。如果j<b且z<>p-1,設z=z^2 mod p,然後回到(4)。如果z=p-1,那麽p通過測試,可能為素數。
//(6) 如果j=b 且z<>p-1,不是素數
//數a被當成證據的機率為75%。這意味著當迭代次數為t時,它產生一個假的素數所花費的時間不超過1/4^t。
//實際上,對大多數隨機數,幾乎99.99%肯定a是證據。
/*Rabin-Miller*/<br /> public static Boolean RabinMiller(int p)<br /> {<br /> //首先選擇一個代測的隨機數p,計算b,b是2整除p-1的次數。然後計算m,使得p=1+(2^b)m,即 m = (p-1)/(2^b),且m是奇數<br /> int b = 0, m = p - 1; //根據p=1+(2^b)m公式,b=0時m=p-1,這個作為初始值來計算出奇數的m;<br /> while (m % 2 == 0)<br /> {<br /> //m每除一次2,b就要加一次,根據p=1+(2^b)m公式,最後可以得出奇數的m<br /> m /= 2;<br /> b++;<br /> }</p><p> //(1) 選擇一個小於p的隨機數a,且大於2。<br /> Random random = new Random();<br /> int a = random.Next(3, p - 1);</p><p> //(2) 設j=0且z=a^m mod p<br /> int j = 0;<br /> int z = (int)Math.Pow(a, m) % p;</p><p> //(3) 如果z=1或z=p-1,那麽p通過測試,可能使素數<br /> if (z == 1 || z == (p - 1))<br /> {<br /> return true;<br /> }</p><p> //(4) 如果j>0且z=1, 那麽p不是素數<br /> //(5) 設j=j+1。如果j<b且z<>p-1,設z=z^2 mod p,然後回到(4)。如果z=p-1,那麽p通過測試,可能為素數。<br /> //(6) 如果j=b 且z<>p-1,不是素數<br /> while (++j <= b)<br /> {<br /> if (z == p - 1)<br /> {<br /> return true;<br /> }<br /> z = (int)Math.Pow(z, 2) % p;<br /> }<br /> return false;<br /> }