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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

素性测试的Miller-Rabin算法完全解析 (C语言实现、Python实现)

發布時間:2023/12/10 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 素性测试的Miller-Rabin算法完全解析 (C语言实现、Python实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

因為文中存在公式,只能用圖片方式上傳了!

?

以下為C語言源代碼:

#include <stdio.h>
typedef long long unsigned LLU;
typedef int BOOL;
#define TRUE 1
#define FALSE 0

BOOL isPrime(LLU n) {? //這是傳統的方法,用于與Miller-Rabin算法的結果進行對比。
? ? if( (n&1)==0 || n%5==0)
? ? ? ? return FALSE;

? ? LLU i,bnd;
? ? bnd=sqrt(n);
? ? for(i=2; i<=bnd; i++)
? ? ? ? if(n%i==0)
? ? ? ? ? ? return FALSE;

? ? return TRUE;
}

//實現(a*b)%c,用類似快速冪的方式實現。
//將模運算下的乘法用加法實現的思想是時間換空間。
//這可以作為典型的時間換空間的例子。
LLU quickMult(LLU a,LLU b,LLU c){
? ? LLU result=0;
? ? while(b>0) {
? ? ? ? if(b&1)
? ? ? ? ? ? result=(result+a)%c;
? ? ? ? a=(a+a)%c;
? ? ? ? b>>=1;
? ? }
? ? return result;
}

//請注意,計算快速冪時,因為變量的數據類型為long long,是64bits長度的整數。
//a的值不能大于(2的32次方-1)≈4000000000
//否則,計算a*a時會越界,超過64bits整數的表示范圍。
//例如a,b,c分別為:7087881096594 10000000000036 10000000000037時,
//正確結果 (a^b)%c=1,但是,在此計算的結果不為1。
//因此,可以改進為用“快速乘”代替*乘法運算符,能更加充分第利用64的long long unsigned型的存儲空間。
//這個例子可以作為算法改進從O(n)到O(lg(n))的進步的例子。
LLU quickPower(LLU a,LLU b,LLU c) {
? ? LLU result=1;
? ? while(b>0) {
? ? ? ? if(b&1)
? ? ? ? ? ? //result=result*a%c; //此為直接乘法
? ? ? ? ? ? result=quickMult(result,a,c);
? ? ? ? //a=a*a%c; //此為直接乘法
? ? ? ? a=quickMult(a,a,c);
? ? ? ? b>>=1;
? ? }
? ? return result;
}

//如果返回值為TRUE表示n為素數,返回值為FALSE表示n為合數。
BOOL MillerRabinPrimeTest(LLU n) {
? ? LLU d,x,newX,a=1;
? ? int i;
? ? for (i=0; i<4; i++)
? ? ? ? a*=rand();
? ? a=a%(n-3)+2;//隨機第選取一個a∈[2,n-2]
? ? //printf("隨機選取的a=%lld\n",a);
? ? int s=0;//s為d中的因子2的冪次數。
? ? d=n-1; ?//d取初值n-1
? ? while( (d&1)==0) {//將d中因子2全部提取出來。
? ? ? ? s++;
? ? ? ? d>>=1;
? ? }

? ? x=quickPower(a,d,n);
? ? for(i=0; i<s; i++) { //進行s次二次探測
? ? ? ? newX=quickPower(x,2,n);
? ? ? ? if(newX==1 && x!=1 && x!=n-1)
? ? ? ? ? ? return FALSE; //用二次定理的逆否命題,此時n確定為合數。
? ? ? ? x=newX;
? ? }
? ? if(x!=1)
? ? ? ? return FALSE; ? //用費馬小定理的逆否命題判斷,此時x=a^(n-1) (mod n),那么n確定為合數。

? ? return TRUE; //用費馬小定理的逆命題判斷。能經受住考驗至此的數,大概率為素數。
}

//經過連續特定次數的Miller-Rabin測試后,
//如果返回值為TRUE表示n為素數,返回值為FALSE表示n為合數。
BOOL isPrimeByMR(LLU n) {
? ? if((n&1)==0 || n%5==0)
? ? ? ? return FALSE;
? ? int i;
? ? for (i=0; i<100; i++)
? ? ? ? if(MillerRabinPrimeTest(n)==FALSE)
? ? ? ? ? ? return FALSE;
? ? return TRUE;
}

//對比傳統方法和Miller-Rabin算法的結果
void check(LLU n) {
? ? char isRight;
? ? BOOL resultA,resultB;
? ? resultA=isPrime(n);
? ? resultB=isPrimeByMR(n);
? ? if(resultA==resultB) {
? ? ? ? isRight='V';
? ? ? ? printf("%c,%llu %d %d\n",isRight,n,resultA,resultB);
? ? } else {
? ? ? ? isRight='X';
? ? ? ? printf("%c,%llu %d %d\n",isRight,n,resultA,resultB);
? ? }
}

//測試任務:在本人筆記本電腦上測試,N=10的18次方至N+10之間的質數為:
//1000000000000000003
//1000000000000000009
//Miller-Rabin算法的速度:0.22秒
//常規算法:22秒
int main() {? ??
? ? srand(time(NULL));

? ? LLU i,n,N;
? ? N=1000000000000000000;
? ? BOOL result;
? ? for(i=N; i<N+10; i++) {
? ? ? ? n=i;
? ? ? ? //check(n);? ? ? ??
? ? ? ? //result=isPrime(n);
? ? ? ? result=isPrimeByMR(n);
? ? ? ? if(result==TRUE)
? ? ? ? ? ? printf("%llu\n",n);

? ? }
? ? return 0;
}

?

以下為Python語言源代碼:

import math import randomdef isPrime(n): #這是傳統的方法,用于與Miller-Rabin算法的結果進行對比。if (n & 1) == 0 or n % 5 == 0:return Falsebnd = int(math.sqrt(n))for i in range(2, bnd + 1):if n % i == 0:return Falsereturn True# 實現(a*b)%c,用類似快速冪的方式實現。 # 將模運算下的乘法用加法實現的思想是時間換空間。 # 這可以作為典型的時間換空間的例子。 def quickMult(a, b, c):result = 0while b > 0:if b & 1:result = (result + a) % ca = (a + a) % cb >>= 1return result#因為Python支持大整數運算,所以在此也可以不用快速乘法,而直接使用乘法*。 def quickPower(a, b, c):result = 1while b > 0:if (b & 1):# result=result*a%c #此為直接乘法result = quickMult(result, a, c)# a=a*a%c #此為直接乘法a = quickMult(a, a, c)b >>= 1return result#如果返回值為TRUE表示n為素數,返回值為FALSE表示n為合數。 def MillerRabinPrimeTest(n):a = random.randint(2,n-2) #隨機第選取一個a∈[2,n-2]# print("隨機選取的a=%lld\n"%a)s = 0 #s為d中的因子2的冪次數。d = n - 1while (d & 1) == 0: #將d中因子2全部提取出來。s += 1d >>= 1x = quickPower(a, d, n)for i in range(s): #進行s次二次探測newX = quickPower(x, 2, n)if newX == 1 and x != 1 and x != n - 1:return False #用二次定理的逆否命題,此時n確定為合數。x = newXif x != 1: # 用費馬小定理的逆否命題判斷,此時x=a^(n-1) (mod n),那么n確定為合數。return Falsereturn True # 用費馬小定理的逆命題判斷。能經受住考驗至此的數,大概率為素數。# 經過連續特定次數的Miller-Rabin測試后, # 如果返回值為TRUE表示n為素數,返回值為FALSE表示n為合數。 def isPrimeByMR(n):if ((n & 1) == 0 or n % 5 == 0):return Falsefor i in range(100):if MillerRabinPrimeTest(n) == False:return Falsereturn True#對比傳統方法和Miller-Rabin算法的結果 def check(n):resultA = isPrime(n)resultB = isPrimeByMR(n)if resultA == resultB:isRight = 'V'print("%c,%u %d %d" % (isRight, n, resultA, resultB))else:isRight = 'X'print("%c,%u %d %d" % (isRight, n, resultA, resultB))# 測試任務:在本人筆記本電腦上測試,N=10的18次方至N+10之間的質數為: # 1000000000000000003 # 1000000000000000009 # Miller-Rabin算法的速度:0.22秒 # 常規算法:22秒 # python的常規算法,耗時更長。 def main():# freopen("result.txt","w",stdout)random.seed()# res=quickPower(2,10,7)# print("%u"%res)N = 1000000000000000000for i in range(N, N + 10):n = i#check(n)# n=int(input())#result=isPrime(n)result = isPrimeByMR(n)if result == True :print("%u" % n)return 0# print(isPrime(1000000000000000003)) # a, b, c = [int(e) for e in input().split(" ")] # print(quickPower(a,b,c)) # # 7087881096594 10000000000036 10000000000037 =1 main()

總結

以上是生活随笔為你收集整理的素性测试的Miller-Rabin算法完全解析 (C语言实现、Python实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。