Miller Rabin演算法詳解

来源:https://www.cnblogs.com/zwfymqz/archive/2017/12/30/8150969.html
-Advertisement-
Play Games

何為Miller Rabin演算法 首先看一下度娘的解釋(如果你懶得讀直接跳過就可以反正也沒啥亂用:joy:) Miller-Rabin演算法是目前主流的基於概率的素數測試演算法,在構建密碼安全體系中占有重要的地位。通過比較各種素數測試演算法和對Miller-Rabin演算法進行的仔細研究,證明在電腦中構建 ...


何為Miller Rabin演算法

首先看一下度娘的解釋(如果你懶得讀直接跳過就可以反正也沒啥亂用:joy:)

Miller-Rabin演算法是目前主流的基於概率的素數測試演算法,在構建密碼安全體系中占有重要的地位。通過比較各種素數測試演算法和對Miller-Rabin演算法進行的仔細研究,證明在電腦中構建密碼安全體系時, Miller-Rabin演算法是完成素數測試的最佳選擇。通過對Miller-Rabin 算 法底層運算的優化,可以取得較以往實現更好的性能。[1]  隨著信息技術的發展、網路的普及和電子商務的開展, 信息安全逐步顯示出了其重要性。信息的泄密、偽造、篡改 等問題會給信息的合法擁有者帶來重大的損失。在電腦中構建密碼安全體系可以提供4種最基本的保護信息安全的服 務:保密性、數據完整性、鑒別、抗抵賴性,從而可以很大 程度上保護用戶的數據安全。在密碼安全體系中,公開密鑰 演算法在密鑰交換、密鑰管理、身份認證等問題的處理上極其有效,因此在整個體系中占有重要的地位。目前的公開密鑰 演算法大部分基於大整數分解、有限域上的離散對數問題和橢 圓曲線上的離散對數問題,這些數學難題的構建大部分都需 要生成一種超大的素數,尤其在經典的RSA演算法中,生成的素數的質量對系統的安全性有很大的影響。目前大素數的生 成,尤其是隨機大素數的生成主要是使用素數測試演算法,本 文主要針對目前主流的Miller-Rabin 演算法進行全面系統的分析 和研究,並對其實現進行了優化

說白了Miller Rabin演算法在信息學奧賽中的應用就一句話:

判斷一個數是否是素數

定理

Miller Rabin演算法的依據是費馬小定理:

$$a^{p-1}\equiv 1\left( modP\right)$$

證明:

性質1:$p-1$個整數$a,2a,3a,...(p-1)a$中沒有一個是$p$的倍數 

性質2:$a,2a,3a,...(p-1)a$中沒有任何兩個同餘與模$p$的

所以$a,2a,3a,...(p-1)a$對模$p$的同餘既不為零,也沒有兩個同餘相同

因此,這$p-1$個數模$p$的同餘一定是$a,2a,3a,...(p-1)a$的某一種排列

即$a,2a,3a,...(p-1)a \equiv {1,2,3,...,p-1}! (mod p)$

化簡為

$a^{p-1}*(p-1)! \equiv {p-1}! (mod p)$

根據威爾遜定理可知$(p-1)!$與$p$互質,所以同時約去$(p-1)!$

即得到$a^{p-1}\equiv 1\left( modP\right)$

 

那麼是不是當一個數$p$滿足任意$a$使得$a^{p-1}\equiv 1\left( modP\right)$成立的時候它就是素數呢?

在費馬小定理被證明後的很長一段時間里,人們都覺得這是很顯然的,

但是終於有一天,人們給出了反例 ,推翻了這個結論

 

這是否意味著利用費馬小定理的思想去判斷素數的思想就是錯誤的呢?

答案是肯定的。

但是如果我們可以人為的把出錯率降到非常小呢?

比如,對於一個數,我們有$99.99999$%的幾率做出正確判斷,那這種演算法不也很優越麽?

 

於是Miller Rabin演算法誕生了!

 

首先介紹一下二次探測定理

若$p$為素數,$a^{2}\equiv 1\left( modP\right)$,那麼$a\equiv \pm 1\left( modP\right)$

證明

$a^{2}\equiv 1\left( modP\right)$

$a^{2}-1\equiv 0\left( modP\right)$

$(a+1)*(a-1)\equiv 0\left( modP\right)$

那麼

$(a+1)\equiv 0\left( modP\right)$

$(a-1)\equiv 0\left( modP\right)$

$a\equiv \pm 1\left( modP\right)$

 

這個定理和素數判定有什麼用呢?

首先,根據Miller Rabin演算法的過程

假設需要判斷的數是$p$

(博主亂入:以下內容較抽象,請仔細理解:joy:)

我們把$p-1$分解為$2^k*t$的形式

然後隨機選擇一個數$a$,計算出$a^t mod p$

讓其不斷的$*2$,同時結合二次探測定理進行判斷

如果我們$*2$後的數$mod p == 1$,但是之前的數$mod p != \pm 1$

那麼這個數就是合數(違背了二次探測定理)

這樣乘$k$次,最後得到的數就是$a^{p-1}$

那麼如果最後計算出的數不為$1$,這個數也是合數(費馬小定理)

正確性

老祖宗告訴我們:joy::若$p$通過一次測試,則$p$不是素數的概率為$25$%

那麼經過$t$輪測試,$p$不是素數的概率為$\dfrac {1}{4^{t}}$

我習慣用$2,3,5,7,11,13,17,19$這幾個數進行判斷

在信息學範圍內出錯率為$0$%(不帶高精:joy:)

code

註意在進行素數判斷的時候需要用到快速冪。。

這個應該比較簡單,就不細講了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#define LL long long 
using namespace std;
const LL MAXN=2*1e7+10;
const LL INF=1e7+10;
inline char nc()
{
    static char buf[MAXN],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
}
inline LL read()
{
    char c=nc();LL x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}
    return x*f;
}
LL fastpow(LL a,LL p,LL mod)
{
    LL base=1;
    while(p)
    {
        if(p&1) base=(base*a)%mod;
        a=(a*a)%mod;
        p>>=1;
    }
    return base;
}
LL num[]= {2,3,5,7,11,13,17,19};
bool Miller_Rabin(LL n)
{
    if (n==2) return 1;
    if((n&1)==0||n==1) return false;
    for (LL i=0; i<8; i++) if (n==num[i]) return 1;
    
    LL temp=n-1,t=0,nxt;
    while((temp&1)==0) temp>>=1,t++;
    
    for(LL i=0;i<8;i++)
    {
        LL a=num[i];
        LL now=fastpow(a,temp,n);
        nxt=now;
        for(LL j=1;j<=t;j++)
        {
            nxt=(now*now)%n;
            if(nxt==1&&now!=n-1&&now!=1) return false;
            now=nxt;
        }
        if(now!=1) return false;
    }
    return true;
}
int main()
{
    #ifdef WIN32
    freopen("a.in","r",stdin);
    #else
    #endif 
    LL N=read(),M=read();
    while(M--)
    {
        LL opt=read();
        if(Miller_Rabin(opt))    printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文主要介紹Spring中, 1 Bean 的 init-method 和 destroy-method 2 集合類型的裝配 3 註解方式裝配 4 以自動掃描把組件納入spring容器中管理 5 代理模式 一、Bean 的 init-method 和 destroy-method 以前在學Servl ...
  • 1.JDK API中RandomAccessFile類的描述 此類的實例支持對隨機訪問文件的讀取和寫入。隨機訪問文件的行為類似存儲在文件系統中的一個大型 byte 數組。存在指向該隱含數組的游標或索引,稱為文件指針;輸入操作從文件指針開始讀取位元組,並隨著對位元組的讀取而前移此文件指針。如果隨機訪問文件 ...
  • 字元流按字元個數輸入、輸出數據。 1.Reader類和FileReader類 Reader類是字元輸入流的超類,FileReader類是讀取字元的便捷類,此處的便捷是相對於其父類(另一個字元輸入流)InputStreamReader而言的。 read()每單字元讀取: read(char[] c)讀 ...
  • 概述 既然決定把視頻上老師講的實戰都自己動手實現一遍,那麼就先把最好大學排名這個實例自己寫一遍。看視頻的時候挺輕鬆的,但是到自己動手的時候才知道不容易,寫這個程式遇到兩個比較棘手的問題,一個是如何從網頁中提取出自己想要的信息,另一個是信息以什麼樣的形式保存並展示出來。其實幾乎所有的爬蟲都會遇到這兩個 ...
  • ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildPr ...
  • 1 class Person(): 2 def __init__(self, name): 3 self.name = name 4 5 6 def print_name(self): 7 print(self.name) 8 9 p = Person('Li') 10 import types 1... ...
  • 非原創,系轉載。 ...
  • 1.JDK API 中關於Serializable的描述 類通過實現 java.io.Serializable 介面以啟用其序列化功能。未實現此介面的類將無法使其任何狀態序列化或反序列化。可序列化類的所有子類型本身都是可序列化的。序列化介面沒有方法或欄位,僅用於標識可序列化的語義。 序列化運行時使用 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...