初等数论--同余--MILLER-RABIN素性检测算法优化
初等數(shù)論--同余--MILLER-RABIN素性檢測算法優(yōu)化
- Euler theorem、Fermat's little theorem
- Primality Test: Fermat、MILLER-RABIN、IMPROVED
- 代碼驗(yàn)證
博主是初學(xué)初等數(shù)論(整除+同余+原根),本意是想整理一些較難理解的定理、算法,加深記憶也方便日后查找;如果有錯(cuò),歡迎指正。
我整理成一個(gè)系列:初等數(shù)論,方便檢索。
這一章不同于前幾章,是我自己總結(jié)的素性檢測算法規(guī)律以及探索一些可優(yōu)化的地方。
Euler theorem、Fermat’s little theorem
具體的定理內(nèi)容以及證明,我在前幾章已經(jīng)記錄過。
- 歐拉定理:設(shè)n∈N+,a∈Z,(a,n)=1,則aφ(n)≡1(modn)歐拉定理:設(shè)n\in N^+,a\in Z,(a,n)=1,則a^{\varphi(n)}\equiv 1(mod n)歐拉定理:設(shè)n∈N+,a∈Z,(a,n)=1,則aφ(n)≡1(modn)
- 費(fèi)馬小定理:設(shè)n為素?cái)?shù),a∈Z,則an≡a(modn)費(fèi)馬小定理:設(shè)n為素?cái)?shù),a\in Z,則a^n\equiv a(mod n)費(fèi)馬小定理:設(shè)n為素數(shù),a∈Z,則an≡a(modn)
可以看出,Fermat’s little theorem的條件更嚴(yán)格,要求是n為素?cái)?shù),而歐拉定理只要求a與n互素即可,并沒有要求n本身為素?cái)?shù)。
目前我學(xué)習(xí)到的素性檢測算法都是以Fermat’s little theorem作為依據(jù),應(yīng)該是因?yàn)镕ermat’s little theorem的條件,必須是素?cái)?shù)。下面我具體來談?wù)勎覍W(xué)習(xí)到的幾個(gè)素性檢測算法。
Primality Test: Fermat、MILLER-RABIN、IMPROVED
素性檢測算法的目的都是一樣的:通過滿足某些條件,來判斷是素?cái)?shù)的概率,檢測越多次概率越大,但是沒法把所有數(shù)都遍歷,所以概率不會(huì)到100%。
Fermat’s little theorem是通過n是素?cái)?shù)的條件,推出a,n滿足哪些結(jié)論。素性檢測算法的手段也都是一樣的:通過a,n或者其他參數(shù)滿足哪些條件,判斷n是素?cái)?shù)的概率。
- Fermat素性檢測算法:n為奇數(shù),通過多次隨機(jī)取b∈Z,有(b,n)=1,判斷bn?1≡0(modn)b\in Z,有(b,n)=1,判斷b^{n-1}\equiv 0(mod n)b∈Z,有(b,n)=1,判斷bn?1≡0(modn)來逐步提高n是素?cái)?shù)的概率。(n如果是奇合數(shù),則被稱為對(duì)于基b的偽素?cái)?shù))
- MILLER-RABIN算法:更具化了n,使得n的條件更多,“n?1=2st,其中t為奇數(shù),2?t,通過多次隨機(jī)取b∈Z,(b,n)=1,如果b和n滿足條件bt≡1(modn),或存在整數(shù)r,0≤r<s,使得b2rt≡?1(modn)"“n-1=2^st,其中t為奇數(shù),2\nmid t,通過多次隨機(jī)取b\in Z,(b,n)=1,如果b和n滿足條件b^t\equiv 1(mod n),或存在整數(shù)r,0\le r< s,使得b^{2^rt}\equiv -1(mod n)"“n?1=2st,其中t為奇數(shù),2?t,通過多次隨機(jī)取b∈Z,(b,n)=1,如果b和n滿足條件bt≡1(modn),或存在整數(shù)r,0≤r<s,使得b2rt≡?1(modn)"來逐步提高n是素?cái)?shù)的概率。(n如果是奇合數(shù),則被稱為對(duì)于基b的強(qiáng)偽素?cái)?shù))
- IMPROVED算法:更更具化了n,使得n的條件更多,“n?1=2k3lm,其中2?m且3?m,通過多次隨機(jī)取b∈Z,(b,n)=1,如果b和n滿足條件bm≡1(modn),或存在整數(shù)q,0≤q<l,使得b2?3qm+b3qm≡?1(modn)",或存在整數(shù)r,0≤r<k,使得b2r3lm≡?1(modn)"“n-1=2^k3^lm,其中2\nmid m且3\nmid m,通過多次隨機(jī)取b\in Z,(b,n)=1,如果b和n滿足條件b^m\equiv 1(mod n),或存在整數(shù)q,0\le q< l,使得b^{2·3^qm}+b^{3^qm}\equiv -1(mod n)",或存在整數(shù)r,0\le r< k,使得b^{2^r3^lm}\equiv -1(mod n)"“n?1=2k3lm,其中2?m且3?m,通過多次隨機(jī)取b∈Z,(b,n)=1,如果b和n滿足條件bm≡1(modn),或存在整數(shù)q,0≤q<l,使得b2?3qm+b3qm≡?1(modn)",或存在整數(shù)r,0≤r<k,使得b2r3lm≡?1(modn)"來逐步提高n是素?cái)?shù)的概率。
可以看出,條件逐漸變得嚴(yán)格。有時(shí)候某些數(shù)可以通過Fermat素性檢測算法,卻不能通過MILLER-RABIN算法;可以通過MILLER-RABIN算法卻不能通過IMPROVED算法。
這是因?yàn)楸葘?duì)這兩種算法,其實(shí)是把Fermat素性檢測算法的一個(gè)條件進(jìn)一步拆分成(s+1)個(gè)條件,MILLER-RABIN算法繼續(xù)到IMPROVED算法,也是把1個(gè)條件繼續(xù)拆分成(l+1)個(gè)條件。
我們是通過條件中有“0”項(xiàng)來判斷整體為“0”,從而素?cái)?shù)可能性提高。也就是說,條件項(xiàng)皆不為0,則不能通過素性檢測。有沒有可能某一個(gè)數(shù)對(duì)于IMPROVED算法,皆不為0,可是對(duì)于MILLER-RABIN算法為0呢?應(yīng)該是有的,即(l+1)個(gè)分項(xiàng)不為0,但是(l+1)個(gè)分項(xiàng)的乘積為0。即可能存在"b2?3qm+b3qm≡?1(modn)不滿足,bm≡1(modn)不滿足,卻滿足bt≡1(modn).b^{2·3^qm}+b^{3^qm}\equiv -1(mod n)不滿足,b^m\equiv 1(mod n)不滿足,卻滿足b^t\equiv 1(mod n).b2?3qm+b3qm≡?1(modn)不滿足,bm≡1(modn)不滿足,卻滿足bt≡1(modn)."
代碼驗(yàn)證
具體數(shù)字需要代碼實(shí)現(xiàn)驗(yàn)證,此工作正在進(jìn)行中……
實(shí)現(xiàn)了Fermat素性檢測算法,和MILLER-RABIN素性檢測算法,以2為底,primeTable是0-10w內(nèi)所有素?cái)?shù),生成算法沒有貼上來。
以下是Fermat素性檢測算法代碼:
from random import random# 利用輾轉(zhuǎn)相除法求最大公因數(shù) def BFactor(a, b):# 若b>a,則交換兩個(gè)數(shù)的值if (b > a):t = aa = bb = tr = b # 初始化rwhile (r != 0):r = a % b # r為a/b的余數(shù)a = bb = rreturn a # 得到最后的a為(a,b)# n = int(input("請(qǐng)輸入需要檢測的整數(shù)n:")) # K = int(input("請(qǐng)輸入循環(huán)次數(shù)k:"))False_Prime_founded = []def fermat_test(n, K):k = 0while (k < K):flag = False# while (not flag):# b = int(random() * (n - 4) + 2) # 生成一個(gè)[2,n-2]之間的隨機(jī)整數(shù)# if (b >= 2 and b <= n - 2):# flag = Trueb = 2factor = BFactor(b, n) # 計(jì)算(b,n)r = (b ** (n - 1)) % n # 計(jì)算b^(n-1)modnprint("k=" + str(k + 1) + "時(shí),取b=" + str(b), end=",")print("g=(" + str(b) + "," + str(n) + ")=" + str(factor), end=',')print("r=" + str(b) + "^" + str(n - 1) + "(mod " + str(n) + ")=" + str(r), end=',')if (factor > 1):print("故n=" + str(n) + "為合數(shù)")breakelif (r != 1):print("故n=" + str(n) + "為合數(shù)")breakelse:print("故n=" + str(n) + "可能為素?cái)?shù)")k += 1if (k == K and n not in primeTable):False_Prime_founded.append(n)print("所以, n=" + str(n) + "可能為素?cái)?shù),n為素?cái)?shù)的概率為" + str((1 - 1 / (2 ** k)) * 100) + "%")def run():for i in range(5, 100000):print(i)fermat_test(i, 1)print("找到的素?cái)?shù):" + str(False_Prime_founded))# 遍歷整數(shù),直至找到偽素?cái)?shù)run()以下是MILLER-RABIN素性檢測算法代碼:
import decimal from random import random from decimal import Decimal, localcontext import mathdecimal.getcontext().prec = 100000000# 輾轉(zhuǎn)相除法找最大公因數(shù)(a,b) def BFactor(a, b):if b > a:t = ab = ta = bq = bwhile (q != 0):q = a % ba = bb = qreturn b# n = int(input("請(qǐng)輸入需要檢測的整數(shù)n:")) # K = int(input("請(qǐng)輸入循環(huán)次數(shù)k:"))MI_False_Prime_founded = []def MILLER_RABIN(n, K):k = 0while (k < K):t = n - 1while (t % 2 == 0):print(t)t /= 2print("n: " + str(n) + "t: " + str(t))print("n-1/t:" + str((n - 1) / t))s = int(math.log((n - 1) / t, 2))print("s" + str(s))flag = False# while (not flag):# b = int(random() * (n - 4) + 2) # 生成一個(gè)[2,n-2]之間的隨機(jī)整數(shù)# if (b >= 2 and b <= n - 2):# flag = Trueb = 2factor = BFactor(b, n) # 計(jì)算(b,n)print("t: " + str(t))x = Decimal(Decimal(pow(Decimal(b), Decimal(t))) % Decimal(n)) # 計(jì)算b^tmodny = []print("vafac")for r in range(1, s):print("avsdfavafaa")print("s" + str(s))y.append(Decimal(pow(b, (Decimal(pow(2, r) * t)))))print(y)# print("包含2的次冪:"+str(y))# print("k=" + str(k + 1) + "時(shí),取b=" + str(b), end=",")# print("g=(" + str(b) + "," + str(n) + ")=" + str(factor), end=',')# # print("r=" + str(b) + "^" + str(n - 1) + "(mod " + str(n) + ")=" + str(r), end=',')for i in y:print("i: " + str(i))print("n: " + str(n))print("i%n: " + str(int(i) % n))if int(i) % n == n - 1:print("故n=" + str(n) + "可能為素?cái)?shù)")MI_False_Prime_founded.append(n)breakif factor > 1:print("factor: " + str(factor))print("數(shù)字1")print("故n=" + str(n) + "為合數(shù)")breakif x == 1 or x == -1:print("數(shù)字2")print("故n=" + str(n) + "可能為素?cái)?shù)")MI_False_Prime_founded.append(n)# if p== -1 for p in y:# if p# print("故n=" + str(n) + "可能為素?cái)?shù)")# k = k + 1else:print("故n=" + str(n) + "為合數(shù)")k += 1# if (k == K):# print("數(shù)字3")# MI_False_Prime_founded.append(n)# print("所以, n=" + str(n) + "可能為素?cái)?shù),n為素?cái)?shù)的概率為" + str((1 - 1 / (2 ** k)) * 100) + "%")def run():for i in primeTable:print(i)MILLER_RABIN(i, 1)print("找到的素?cái)?shù):" + str(MI_False_Prime_founded))primeTable = [341, 561, 645, 1105, 1387, 1729, 1905, 2047, 2465, 2701, 2821, 3277, 4033, 4369, 4371, 4681, 5461, 6601,7957, 8321, 8481, 8911, 10261, 10585, 11305, 12801, 13741, 13747, 13981, 14491, 15709, 15841, 16705,18705, 18721, 19951, 23001, 23377, 25761, 29341, 30121, 30889, 31417, 31609, 31621, 33153, 34945, 35333,39865, 41041, 41665, 42799, 46657, 49141, 49981, 52633, 55245, 57421, 60701, 60787, 62745, 63973, 65077,65281, 68101, 72885, 74665, 75361, 80581, 83333, 83665, 85489, 87249, 88357, 88561, 90751, 91001, 93961]run()找到的偽素?cái)?shù)分別是:
-
Fermat算法找到的“素?cái)?shù)”:[341, 561, 645, 1105, 1387, 1729, 1905, 2047, 2465, 2701, 2821, 3277, 4033, 4369, 4371, 4681, 5461, 6601, 7957, 8321, 8481, 8911, 10261, 10585, 11305, 12801, 13741, 13747, 13981, 14491, 15709, 15841, 16705, 18705, 18721, 19951, 23001, 23377, 25761, 29341, 30121, 30889, 31417, 31609, 31621, 33153, 34945, 35333, 39865, 41041, 41665, 42799, 46657, 49141, 49981, 52633, 55245, 57421, 60701, 60787, 62745, 63973, 65077, 65281, 68101, 72885, 74665, 75361, 80581, 83333, 83665, 85489, 87249, 88357, 88561, 90751, 91001, 93961]
-
MILLER-RABIN算法找到的“素?cái)?shù)”:[2047, 3277, 4033, 4681, 8321, 15841, 29341, 42799, 49141, 52633, 65281, 74665, 80581, 85489, 88357, 90751]
總結(jié)
以上是生活随笔為你收集整理的初等数论--同余--MILLER-RABIN素性检测算法优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 初等数论--同余--MILLER-RAB
- 下一篇: 初等数论--同余方程--二元一次不定方程