1. 程式人生 > >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 \pmod P$$

證明:

性質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)} \pmod p$

化簡為

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

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

即得到$a^{p-1}\equiv 1 \pmod P$

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

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

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

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

答案是肯定的。

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

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

於是Miller Rabin演算法誕生了!

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

若$p$為素數,$a^{2}\equiv 1 \pmod P$,那麼$a\equiv \pm 1 \pmod P$

證明

$a^{2}\equiv 1 \pmod P$

$a^{2}-1\equiv 0 \pmod P$

$(a+1)*(a-1)\equiv 0 \pmod P$

那麼

$(a+1)\equiv 0 \pmod P$

或者

$(a-1)\equiv 0 \pmod P$

(此處可根據唯一分解定理證明)

$a\equiv \pm 1 \pmod P$

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

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

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

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

當$p$是素數,有$a ^ {2^k * t} \equiv 1 \pmod p$

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

讓其不斷的自乘,同時結合二次探測定理進行判斷

如果我們自乘後的數$\pmod p = 1$,但是之前的數$\pmod p \not = \pm 1$

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

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

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

正確性

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

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

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

在資訊學範圍內出錯率為$0$%(不帶高精)

code

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

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

#include<cstdio>
#define LL long long 
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, M, Test[10] = {2, 3, 5, 7, 11, 13, 17};
int pow(int a, int p, int mod) {
    int base = 1;
    for(; p; p >>= 1, a = (1ll * a * a) % mod) 
        if(p & 1) base = (1ll * base * a) % mod;
    return base % mod;
}
bool Query(int P) {
    if(P == 1) return 0;
    int t = P - 1, k = 0;
    while(!(t & 1)) k++, t >>= 1;
    for(int i = 0; i < 4; i++) {
        if(P == Test[i]) return 1;
        LL a = pow(Test[i], t, P), nxt = a;
        for(int j = 1; j <= k; j++) {
            nxt = (a * a) % P;
            if(nxt == 1 && a != 1 && a != P - 1) return 0;
            a = nxt;
        }
        if(a != 1) return 0;
    }
    return 1;
}
main() { 
    N = read(); M = read();    
    while(M--) puts(Query(read()) ? "Yes" : "No");
}

相關推薦

Miller Rabin演算法

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

Miller-Rabin素性測試演算法

看了一些別人的部落格,發現裡面涉及到的公式沒有證明,於是就打算自己寫一篇比較詳細的講解。 先看兩個引理及其證明(建議把證明搞懂)。 PS:以下圖片均為作者用wps製作,如想使用請附上作者部落格連結,謝

面試演算法之字串匹配演算法Rabin-Karp演算法

既然談論到字串相關演算法,那麼字串匹配是根本繞不過去的坎。在面試中,面試官可能會要你寫或談談字串的匹配演算法,也就是給定兩個字串,s 和 t, s是要查詢的字串,t是被查詢的文字,要求你給出一個演算法,找到s在t中第一次出現的位置,假定s為 acd, t為a

php openssl_sign() 語法+RSA公私鑰加密解密,非對稱加密演算法

其實有時候覺得寫部落格好煩,就個函式就開篇部落格。很小的意見事情而已,知道的人看來多取一舉,或者說沒什麼必要,浪費時間,不知道的人就會很鬱悶。技術就是這樣的,懂的人覺得真的很簡單啊,不知道的人真的好難。。。 一般在跟第三方介面對接資料的時候,為了保證很多都使用的RSA簽名,沒性趣瞭解的同學只需要

Show, attend and tell演算法及原始碼

mark一下,感謝作者分享! https://blog.csdn.net/shenxiaolu1984/article/details/51493673 原論文:https://arxiv.org/pdf/1502.03044v2.pdf 原始碼:https://github.c

資料分析學習之不得不知的八大演算法

學習資料分析的朋友們都知道,演算法是不可或缺的,或者說演算法在一定程度上可以更好的量化的一個人的學習能力和水平,本文感謝科多大資料的馮老師,由他整理了經典的八大演算法,相關的資料希望能幫助大家瞭解。 演算法一:快速排序法 快速排序是由東尼 · 霍爾所發展的一種排序演算法。在平均狀況下,排序

程式設計思想 - 五大常用演算法

https://www.cnblogs.com/brucemengbm/p/6875340.html https://blog.csdn.net/changyuanchn/article/details/51476281 https://www.cnblogs.com/chuninggao/p/

Kadane演算法及求解最大子數列和問題

最大子數列和問題         給出一個數列,現在求其中一個子數列,要求是所有子數列的和的最大值。另外還有其他問法,例如給出一個數組,要求求出連續的元素和的最大值。可以一個例子來解釋: 假設有數列:[-1,2,3,-5,6,-2,4],那麼總共有

K-NN近鄰演算法

 K-近鄰演算法屬於一種監督學習分類演算法,該方法的思路是:如果一個樣本在特徵空間中的k個最相似(即特徵空間中最鄰近)的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別。  (1) 需要進行分類,分類的依據是什麼呢,每個物體都有它的特徵點,這個就是分類的依據,特徵點可

字典序演算法

一、字典序 字典序,就是按照字典中出現的先後順序進行排序。 1、單個字元 在計算機中,25個字母以及數字字元,字典排序如下: '0' < '1' < '2' < ... < '9' < 'a' < 'b' < ... &l

演算法 】 二維動態規劃

馬攔過河卒 原題傳送門 這一到題目也是比較基礎的動態規劃,也可以理解為是遞推,主要是運用加法原理,思維難度不大。我們要求從 (0,0) ( 0

圖的最小生成樹prim演算法

prim演算法是求圖的最小生成樹的一種演算法,它是根據圖中的節點來進行求解,具體思想大概如下: 首先,將圖的所有節點(我們假定總共有n個節點)分成兩個集合,V和U。其中,集合V儲存的是我們已經訪問過的節點,集合U儲存的是我們未曾訪問的節點。prim演算法第一步就是選定第一個節點放入集合

吳恩達機器學習課程筆記02——處理房價預測問題(梯度下降演算法

  建議記住的實用符號 符號 含義 m 樣本數目 x 輸入變數 y 輸出變數/目標變數

樹鏈剖分演算法

學OI也有一段時間了,感覺該搞點東西了。 於是學習了樹(熟)鏈(練)剖(pou)分(糞) 當然,學習這個演算法是需要先學習線段樹的。不懂的還是再過一段時間吧。 如果碰到一道題,要對一顆樹的兩個點中的最短路徑、以u為根的子樹之類的東西進行修改或者查詢,那麼大概就是樹鏈剖分的題了。 樹鏈剖分就是把一顆

各種排序演算法C++實現

1.氣泡排序 時間複雜度 O ( n

整數拆分演算法

問題描述 輸入一個N,輸出所有拆分的方式。如輸入3 輸出1+1+1 1+2 3 演算法思想 用一個數組res[]存放拆分的解,用全域性變數存放拆分的方法數。divN(n,k)使用n表示要分解的整數,k表示res陣列下標,即第k次拆分。先從divN(n,1)開始,用num表示第

演算法】對於單調棧的重新理解

對於單調棧的重新理解 關於什麼是單調棧和為什麼要用單調棧: 亂頭髮節 地平線 Largest Rectangle in a Histogram 關於什麼是單調棧和為什麼要用單調棧: 單調棧,就是棧中的元

遞迴演算法

1. 何為遞迴? 遞迴在我們的生活中其實很常見。假設你去電影院看電影,黑漆漆一片,你不知道自己來到了第幾排,於是你問前面的人他是第幾排,知道了前面的人是第幾排,加一也就是你所在的排數。但前面的人也不知道,於是他也繼續向前問,直到第一排的人回答他在第一排,然後再依次往後傳,最後

生動的普里姆演算法

一:普里姆演算法的介紹:         針對無向圖用來生成最小生成樹的演算法。 二:普里姆演算法的步驟:         起始條件:         首先你有一個

深度學習 --- BP演算法(誤差反向傳播演算法

本節開始深度學習的第一個演算法BP演算法,本打算第一個演算法為單層感知器,但是感覺太簡單了,不懂得找本書看看就會了,這裡簡要的介紹一下單層感知器: 圖中可以看到,單層感知器很簡單,其實本質上他就是線性分類器,和機器學習中的多元線性迴歸的表示式差不多,因此它具有多元線性迴歸的優點和缺點。