日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java生成大素数_用BigInteger实现大素数生成算法

發(fā)布時(shí)間:2025/3/12 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java生成大素数_用BigInteger实现大素数生成算法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一.通過素?cái)?shù)的基本性質(zhì)

根據(jù)素?cái)?shù)的性質(zhì)(除了1和此整數(shù)(n)自身外,無法被其他自然數(shù)整除的數(shù)):即從2到n/2的數(shù)都不能整除n。

1 public static booleanisPrime(BigInteger num)2 {3 BigInteger two = BigInteger.valueOf(2);4 for(BigInteger i = two; !(i.compareTo(num.divide(two)) == 1); i =i.add(BigInteger.ONE))5 {6 if(num.remainder(i) == BigInteger.ZERO)7 {8 return false;9 }10 }11

12 return true;13 }

用大于2^63的數(shù)去測試,結(jié)果因?yàn)檫\(yùn)算量太大,運(yùn)行半個(gè)來小時(shí)也沒有結(jié)果出現(xiàn)。

二.通過素?cái)?shù)表

要提高速度就要減少進(jìn)入判斷方法中的循環(huán):

1.偶數(shù)可以排除

2.大的合數(shù)(即素?cái)?shù)的積)可以排除

排除偶數(shù)直接增加一個(gè)判斷即可實(shí)現(xiàn),而排除大的合數(shù)也通過產(chǎn)生一個(gè)素?cái)?shù)表實(shí)現(xiàn)。

這里引援51CTO網(wǎng)友 夢朝思夕的BOLG,即“一般來說整除100以內(nèi)的所有素?cái)?shù)可排除76%不是素?cái)?shù)的可能性整除256以內(nèi)的所有素?cái)?shù)可排除80%不是素?cái)?shù)的可能性。” 而我同樣地建大小為2000的表,private?static BigInteger[] primeList = new BigInteger[2000]

primeList[1999] = 17389

for(int i = 0, j = 2; i < 2000; j++)

{if(isPrime(j))

{

primeList[i]=BigInteger.valueOf(j);

i++;

}

}

再來一個(gè)方法判斷新生成的大數(shù)判斷是否為幾個(gè)素?cái)?shù)的積

public static booleanisNotPrimeProduct(BigInteger num)

{for(int i=0;i< 2000; i++)

{if(num.remainder(primeList[i]) ==BigInteger.ZERO)

{return false;

}

}return true;

}

素?cái)?shù)表太大也減慢速度,而且數(shù)值越大,素?cái)?shù)表判別的確定性就越小。要知道,我們要的是2^63。

三.通過費(fèi)馬(Fermat)素?cái)?shù)檢驗(yàn)

在網(wǎng)上查閱資料,知道可以運(yùn)用費(fèi)馬小定理檢驗(yàn)一個(gè)數(shù)是否不是合數(shù)。

費(fèi)馬小定理是數(shù)論中的一個(gè)定理:假如a是一個(gè)整數(shù),p是一個(gè)質(zhì)數(shù),那么

如果a不是p的倍數(shù),這個(gè)定理也可以寫成

根據(jù)費(fèi)馬小定理:如果p是素?cái)?shù),

,那么

如果我們想知道n是否是素?cái)?shù),我們在中間選取a,看看上面等式是否成立。如果對于數(shù)值a等式不成立,那么n是合數(shù)。如果有很多的a能夠使等式成立,那么我們可以說n?可能是素?cái)?shù),或者偽素?cái)?shù)。

在我們檢驗(yàn)過程中,有可能我們選取的a都能讓等式成立,然而n卻是合數(shù)。這時(shí)等式

被稱為Fermat liar。如果我們選取滿足下面等式的a

那么a也就是對于n的合數(shù)判定的Fermat witness。

而在這里我從cnblogs的Knuth_檔案學(xué)到了大量理論知識(shí)和算法的實(shí)現(xiàn)。(特別是蒙哥馬利快速積模算法:計(jì)算大數(shù)(x^y)%z)

用java實(shí)現(xiàn)如下

public staticBigInteger Montgomery(BigInteger n, BigInteger p, BigInteger m)

{

n=n.remainder(m) ;

BigInteger k=BigInteger.ONE;while(p.compareTo(BigInteger.ONE) == 0)

{if(!(p.remainder(BigInteger.ONE) ==BigInteger.ZERO))

{

k=(k.multiply(n)).remainder(m);

}

n=(n.multiply(n)).remainder(m);

p= p.divide(BigInteger.valueOf(2));

}return(n.multiply(k)).remainder(m);

}

接下來,我們就可以對一個(gè)大數(shù)使用費(fèi)馬素?cái)?shù)檢驗(yàn)可以判定這個(gè)大數(shù)是偽素?cái)?shù)。

從前2000素?cái)?shù)一一檢驗(yàn),而費(fèi)馬素?cái)?shù)檢驗(yàn)只是隨機(jī)化了。

public static booleanfermatPrimalityTest(BigInteger num)

{for(int i = 0; i < 2000; i++)

{if(!(Montgomery(primeList[i], num.subtract(BigInteger.ONE), num).compareTo(BigInteger.ONE) == 1)) //(x^y)%z

{return false;

}

}return true;

}

使用素?cái)?shù)表的前十個(gè)結(jié)果:

9223372036854775809

9223372036854775811

9223372036854775813

9223372036854775815

9223372036854775817

9223372036854775819

9223372036854775821

9223372036854775823

9223372036854775825

9223372036854775827

使用費(fèi)馬素?cái)?shù)檢驗(yàn)過的前十個(gè)結(jié)果:

9223372036854775817

9223372036854775837

9223372036854775889

9223372036854775903

9223372036854775907

9223372036854775931

9223372036854775937

9223372036854775939

9223372036854775949

9223372036854775963

四.總結(jié)

現(xiàn)在我們可以通過結(jié)果簡單的分析出出只是使用素?cái)?shù)表的結(jié)果有很多都通不過費(fèi)馬素?cái)?shù)檢驗(yàn),因?yàn)樗財(cái)?shù)表總有上界。最后可以通過Knuth所說的?拉賓米勒測試排除掉那些卡爾麥克(Carmichael)數(shù)。

最后再次感謝?夢朝思夕和 Knuth?兩位技術(shù)前輩,可以說我在這里只是把他們的心得進(jìn)一步總結(jié)。權(quán)當(dāng)筆記。

總結(jié)

以上是生活随笔為你收集整理的java生成大素数_用BigInteger实现大素数生成算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。