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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

记一次使用快速幂与Miller-Rabin的大素数生成算法

發布時間:2025/4/16 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 记一次使用快速幂与Miller-Rabin的大素数生成算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家都知道RSA的加密的安全性就是能夠找到一個合適的大素數,而現在判斷大素數的辦法有許多,比如Fermat素性測試或者Miller-Rabin素性測試,而這里我用了Miller-Rabin素性測試的算法,具體的理論我寫到下面。

?

算法的理論基礎:

  • Fermat定理:若n是奇素數,a是任意正整數(1≤ a≤ n?1),則 a^(n-1) ≡ 1 mod n。
  • ?

    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在(1n-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;

    }

    ???

    ?

    二、實驗結果(自行測試)

    ?

    這是對10000000000000000001000000000000005000里所有素數判定的結果

    ?

    ?

    這是對輸入素數的判讀

    ?

    ?

    ?

    以上結果說明,該程序完全能夠勝任在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的大素数生成算法的全部內容,希望文章能夠幫你解決所遇到的問題。

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