记一次使用快速幂与Miller-Rabin的大素数生成算法
大家都知道RSA的加密的安全性就是能夠找到一個合適的大素數,而現在判斷大素數的辦法有許多,比如Fermat素性測試或者Miller-Rabin素性測試,而這里我用了Miller-Rabin素性測試的算法,具體的理論我寫到下面。
?
算法的理論基礎:
?
2. ?如果n是一個奇素數,將n?1表示成2^s*r的形式,r是奇數,a與n是互素的任何隨機整數,那么a^r ≡ 1 mod n或者對某個j (0 ≤ j≤ s?1, j∈Z) 等式a^(2jr) ≡ ?1 mod n 成立。
?
實驗需要根據這個算法的理論來實現對素數的判定功能,而我將上述理論用C++的 形式寫了出來,然后在一些細節的算法上少做潤色,成功實現了對素數的生成和判定。
?
?
?
一、實驗代碼:
#include<iostream>
#include<cmath>
#include<ctime>
#include<cstdlib> ?
?
using namespace std;
typedef unsigned long long ll;
?
long long q_mul( long long a, long long b, long long mod ) ??
{ ?
????long long ans = 0; ?
????while(b) ?
????{ ?
????????if(b & 1) ?
????????{ ?
????????????b--; ?
????????????ans =(ans+ a)%mod; ?
????????} ?
????????b /= 2; ?
????????a = (a + a) % mod; ?
??
????} ?
????return ans; ?
}
long long q_pow( long long a, long long b, long long mod ) ?
{ ?
????long long ans = 1; ?
????while(b) ?
????{ ?
????????if(b & 1) ?
????????{ ?
????????????ans = q_mul( ans, a, mod ); ?
????????????
????????} ?
????????b /= 2; ?
????????a = q_mul( a, a, mod ); ?
????} ?
????return ans; ?
}
//long long q_pow(ll a,ll b,ll mod){
// ll base=a;
// ll ans = 1;
// while(b!=0){
// if(b&1) ans = (ans*base)%mod;
// base = (base*base)%mod;
// b>>=1;
// }
// return ans;
//}
?
int Miller_Rabin(ll n) {
if(n<2) return 0;
if(n==2) return 1;
?
ll k=0,q=n-1;
while(q%2==0){
q=q/2;
k++;
}
ll a = rand(); //要保證a在(1,n-1)之間,開區間
a=(a%(n-2))+2;
ll result1 = q_pow(a,q,n);
?
if(result1 == 1||result1 == n-1){
?return 1;
}
while(k--){
result1 = q_mul(result1,2,n);
if(result1 == n-1) return 1;
}
?
return 0;
}
bool True_Miller_Rabin(ll n){
int times = 10;
while(times){
times--;
if(Miller_Rabin(n)==0) return false;
}
return true;
}
int main()
{
srand((unsigned)time(NULL));
ll num;
// while(1){
// cin>>num;
// if(Miller_Rabin(num)==1)
// cout<<"為素數"<<endl;
// else{
// cout<<"是合數"<<endl;
// }
// }
for(ll i=1000000;i<=1005000;i++){
int a =0;
if(True_Miller_Rabin(i)){
cout<< i<<"是素數"<<endl;
}
}
?
return 0;
}
???
?
二、實驗結果(自行測試)
?
這是對1000000000000000000到1000000000000005000里所有素數判定的結果
?
?
這是對輸入素數的判讀
?
?
?
以上結果說明,該程序完全能夠勝任在long long類型范圍下的素數判定任務。
?
?
?
?
三、實驗總結
本次實驗采用了Miller-Rabin算法,而在理解算法的基礎上我們要靈活運用。在算法中我最開始用到了C++函數里面的pow函數,然而這個函數導致我素數輸出不完整,經過很久的調試,我發現是C++自帶庫里面的數據類型與long long類型有出入,所以我放棄了使用自帶的函數庫。之后,我選擇了快速冪算法。這個算法比pow函數效果更好,能夠對大數進行快速的冪計算。然而在快速冪計算的過程中設計到兩個數相乘,當兩個Long 類型的數據相乘時會溢出從而導致計算的大素數長度有限。于是我有考慮將冪計算里面的乘法分成若干個加法去進行運算,于是我采用了快速乘與快速冪想結合的方式,也就是我上述代碼中綠色的部分(藍色部分為單純快速冪),由此我講冪運算的速度有提升了一個檔次,在此基礎上也增大了計算素數的范圍。
——————Made By Pinging、、、、、hhh ?Welcome to CUMT。。。
?
轉載于:https://www.cnblogs.com/Pinging/p/7468539.html
總結
以上是生活随笔為你收集整理的记一次使用快速幂与Miller-Rabin的大素数生成算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3.4_函数_Function_Part
- 下一篇: JAVA循环结构