當前位置:首頁 » 操作系統 » 演算法全解

演算法全解

發布時間: 2023-08-29 11:53:23

⑴ 密碼學基礎1:RSA演算法原理全面解析

本節內容中可能用到的符號說明如下:

質數和合數: 質數是指除了平凡約數1和自身之外,沒有其他約數的大於1的正整數。大於1的正整數中不是素數的則為合數。如 7、11 是質數,而 4、9 是合數。在 RSA 演算法中主要用到了質數相關性質,質數可能是上帝留給人類的一把鑰匙,許多數學定理和猜想都跟質數有關。

[定理1] 除法定理: 對任意整數 a 和 任意正整數 n,存在唯一的整數 q 和 r,滿足 。其中, 稱為除法的商,而 稱為除法的余數。

整除: 在除法定理中,當余數 時,表示 a 能被 n 整除,或者說 a 是 n 的倍數,用符號 表示。

約數和倍數 : 對於整數 d 和 a,如果 ,且 ,則我們說 d 是 a 的約數,a 是 d 的倍數。

公約數: 對於整數 d,a,b,如果 d 是 a 的約數且 d 也是 b 的約數,則 d 是 a 和 b 的公約數。如 30 的約數有 1,2,3,5,6,10,15,30,而 24 的約數有 1,2,3,4,6,8,12,24,則 30 和 24 的公約數有 1,2,3,6。其中 1 是任意兩個整數的公約數。

公約數的性質:

最大公約數: 兩個整數最大的公約數稱為最大公約數,用 來表示,如 30 和 24 的最大公約數是 6。 有一些顯而易見的性質:



[定理2] 最大公約數定理: 如果 a 和 b 是不為0的整數,則 是 a 和 b 的線性組合集合 中的最小正元素。

由定理2可以得到一個推論:

[推論1] 對任意整數 a 和 b,如果 且 ,則 。

互質數: 如果兩個整數 a 和 b 只有公因數 1,即 ,則我們就稱這兩個數是互質數(coprime)。比如 4 和 9 是互質數,但是 15 和 25 不是互質數。

互質數的性質:

歐幾里得演算法分為樸素歐幾里得演算法和擴展歐幾里得演算法,樸素法用於求兩個數的最大公約數,而擴展的歐幾里得演算法則有更多廣泛應用,如後面要提到的求一個數對特定模數的模逆元素等。

求兩個非負整數的最大公約數最有名的是 輾轉相除法,最早出現在偉大的數學家歐幾里得在他的經典巨作《幾何原本》中。輾轉相除法演算法求兩個非負整數的最大公約數描述如下:


例如, ,在求解過程中,較大的數縮小,持續進行同樣的計算可以不斷縮小這兩個數直至其中一個變成零。

歐幾里得演算法的python實現如下:

擴展歐幾里得演算法在 RSA 演算法中求模反元素有很重要的應用,定義如下:

定義: 對於不全為 0 的非負整數 ,則必然存在整數對 ,使得

例如,a 為 3,b 為 8,則 。那麼,必然存在整數對 ,滿足 。簡單計算可以得到 滿足要求。

擴展歐幾里得演算法的python實現如下:

同餘: 對於正整數 n 和 整數 a,b,如果滿足 ,即 a-b 是 n 的倍數,則我們稱 a 和 b 對模 n 同餘,記號如下: 例如,因為 ,於是有 。
對於正整數 n,整數 ,如果 則我們可以得到如下性質:

譬如,因為 ,則可以推出 。

另外,若 p 和 q 互質,且 ,則可推出:

此外,模的四則運算還有如下一些性質,證明也比較簡單,略去。

模逆元素: 對整數 a 和正整數 n,a 對模數 n 的模逆元素是指滿足以下條件的整數 b。 a 對 模數 n 的 模逆元素不一定存在,a 對 模數 n 的模逆元素存在的充分必要條件是 a 和 n 互質,這個在後面我們會有證明。若模逆元素存在,也不是唯一的。例如 a=3,n=4,則 a 對模數 n 的模逆元素為 7 + 4k,即 7,11,15,...都是整數 3 對模數 4 的模逆元素。如果 a 和 n 不互質,如 a = 2,n = 4,則不存在模逆元素。

[推論2] 模逆元素存在的充分必要條件是整數 a 和 模數 n 互質。

[定理3] 唯一質數分解定理: 任何一個大於1的正整數 n 都可以 唯一分解 為一組質數的乘積,其中 都是自然數(包括0)。比如 6000 可以唯一分解為 。

由質數唯一分解定理可以得到一個推論: 質數有無窮多個

[定理4] 中國剩餘定理(Chinese remainder theorem,CRT) ,最早見於《孫子算經》(中國南北朝數學著作,公元420-589年),叫物不知數問題,也叫韓信點兵問題。

翻譯過來就是已知一個一元線性同餘方程組求 x 的解:

宋朝著名數學家秦九韶在他的著作中給出了物不知數問題的解法,明朝的數學家程大位甚至編了一個《孫子歌訣》:

意思就是:將除以 3 的余數 2 乘以 70,將除以 5 的余數 3 乘以 21,將除以 7 的余數 2 乘以 15,最終將這三個數相加得到 。再將 233 除以 3,5,7 的最小公倍數 105 得到的余數 ,即為符合要求的最小正整數,實際上, 都符合要求。

物不知數問題解法本質

求解通項公式

中國剩餘定理相當於給出了以下的一元線性同餘方程組的有解的判定條件,並用構造法給出了解的具體形式。

模數 兩兩互質 ,則對任意的整數: ,方程組 有解,且解可以由如下構造方法得到:

並設 是除 以外的其他 個模數的乘積。



中國剩餘定理通項公式證明

⑵ hash演算法原理詳解

散列方法的主要思想是根據結點的關鍵碼值來確定其存儲地址:以關鍵碼值K為自變數,通過一定的函數關系h(K)(稱為散列函數),計算出對應的函數值來,把這個值解釋為結點的存儲地址,將結點存入到此存儲單元中。檢索時,用同樣的方法計算地址,然後到相應的單元里去取要找的結點。通過散列方法可以對結點進行快速檢索。散列(hash,也稱「哈希」)是一種重要的存儲方式,也是一種常見的檢索方法。

按散列存儲方式構造的存儲結構稱為散列表(hash table)。散列表中的一個位置稱為槽(slot)。散列技術的核心是散列函數(hash function)。 對任意給定的動態查找表DL,如果選定了某個「理想的」散列函數h及相應的散列表HT,則對DL中的每個數據元素X。函數值h(X.key)就是X在散列表HT中的存儲位置。插入(或建表)時數據元素X將被安置在該位置上,並且檢索X時也到該位置上去查找。由散列函數決定的存儲位置稱為散列地址。 因此,散列的核心就是:由散列函數決定關鍵碼值(X.key)與散列地址h(X.key)之間的對應關系,通過這種關系來實現組織存儲並進行檢索。

一般情況下,散列表的存儲空間是一個一維數組HT[M],散列地址是數組的下標。設計散列方法的目標,就是設計某個散列函數h,0<=h( K ) < M;對於關鍵碼值K,得到HT[i] = K。 在一般情況下,散列表的空間必須比結點的集合大,此時雖然浪費了一定的空間,但換取的是檢索效率。設散列表的空間大小為M,填入表中的結點數為N,則稱為散列表的負載因子(load factor,也有人翻譯為「裝填因子」)。建立散列表時,若關鍵碼與散列地址是一對一的關系,則在檢索時只需根據散列函數對給定值進行某種運算,即可得到待查結點的存儲位置。但是,散列函數可能對於不相等的關鍵碼計算出相同的散列地址,我們稱該現象為沖突(collision),發生沖突的兩個關鍵碼稱為該散列函數的同義詞。在實際應用中,很少存在不產生沖突的散列函數,我們必須考慮在沖突發生時的處理辦法。

在以下的討論中,我們假設處理的是值為整型的關鍵碼,否則我們總可以建立一種關鍵碼與正整數之間的一一對應關系,從而把該關鍵碼的檢索轉化為對與其對應的正整數的檢索;同時,進一步假定散列函數的值落在0到M-1之間。散列函數的選取原則是:運算盡可能簡單;函數的值域必須在散列表的范圍內;盡可能使得結點均勻分布,也就是盡量讓不同的關鍵碼具有不同的散列函數值。需要考慮各種因素:關鍵碼長度、散列表大小、關鍵碼分布情況、記錄的檢索頻率等等。下面我們介紹幾種常用的散列函數。

顧名思義,除余法就是用關鍵碼x除以M(往往取散列表長度),並取余數作為散列地址。除余法幾乎是最簡單的散列方法,散列函數為: h(x) = x mod M。

使用此方法時,先讓關鍵碼key乘上一個常數A (0< A < 1),提取乘積的小數部分。然後,再用整數n乘以這個值,對結果向下取整,把它做為散列的地址。散列函數為: hash ( key ) = _LOW( n × ( A × key % 1 ) )。 其中,「A × key % 1」表示取 A × key 小數部分,即: A × key % 1 = A × key - _LOW(A × key), 而_LOW(X)是表示對X取下整

由於整數相除的運行速度通常比相乘要慢,所以有意識地避免使用除余法運算可以提高散列演算法的運行時間。平方取中法的具體實現是:先通過求關鍵碼的平方值,從而擴大相近數的差別,然後根據表長度取中間的幾位數(往往取二進制的比特位)作為散列函數值。因為一個乘積的中間幾位數與乘數的每一數位都相關,所以由此產生的散列地址較為均勻。

假設關鍵字集合中的每個關鍵字都是由 s 位數字組成 (u1, u2, …, us),分析關鍵字集中的全體,並從中提取分布均勻的若干位或它們的組合作為地址。數字分析法是取數據元素關鍵字中某些取值較均勻的數字位作為哈希地址的方法。即當關鍵字的位數很多時,可以通過對關鍵字的各位進行分析,丟掉分布不均勻的位,作為哈希值。它只適合於所有關鍵字值已知的情況。通過分析分布情況把關鍵字取值區間轉化為一個較小的關鍵字取值區間。

舉個例子:要構造一個數據元素個數n=80,哈希長度m=100的哈希表。不失一般性,我們這里只給出其中8個關鍵字進行分析,8個關鍵字如下所示:

K1=61317602 K2=61326875 K3=62739628 K4=61343634

K5=62706815 K6=62774638 K7=61381262 K8=61394220

分析上述8個關鍵字可知,關鍵字從左到右的第1、2、3、6位取值比較集中,不宜作為哈希地址,剩餘的第4、5、7、8位取值較均勻,可選取其中的兩位作為哈希地址。設選取最後兩位作為哈希地址,則這8個關鍵字的哈希地址分別為:2,75,28,34,15,38,62,20。

此法適於:能預先估計出全體關鍵字的每一位上各種數字出現的頻度。

將關鍵碼值看成另一種進制的數再轉換成原來進制的數,然後選其中幾位作為散列地址。

例Hash(80127429)=(80127429)13=8 137+0 136+1 135+2 134+7 133+4 132+2*131+9=(502432641)10如果取中間三位作為哈希值,得Hash(80127429)=432
為了獲得良好的哈希函數,可以將幾種方法聯合起來使用,比如先變基,再折疊或平方取中等等,只要散列均勻,就可以隨意拼湊。

有時關鍵碼所含的位數很多,採用平方取中法計算太復雜,則可將關鍵碼分割成位數相同的幾部分(最後一部分的位數可以不同),然後取這幾部分的疊加和(捨去進位)作為散列地址,這方法稱為折疊法。

分為:

盡管散列函數的目標是使得沖突最少,但實際上沖突是無法避免的。因此,我們必須研究沖突解決策略。沖突解決技術可以分為兩類:開散列方法( open hashing,也稱為拉鏈法,separate chaining )和閉散列方法( closed hashing,也稱為開地址方法,open addressing )。這兩種方法的不同之處在於:開散列法把發生沖突的關鍵碼存儲在散列表主表之外,而閉散列法把發生沖突的關鍵碼存儲在表中另一個槽內。

(1)拉鏈法

開散列方法的一種簡單形式是把散列表中的每個槽定義為一個鏈表的表頭。散列到一個特定槽的所有記錄都放到這個槽的鏈表中。圖9-5說明了一個開散列的散列表,這個表中每一個槽存儲一個記錄和一個指向鏈表其餘部分的指針。這7個數存儲在有11個槽的散列表中,使用的散列函數是h(K) = K mod 11。數的插入順序是77、7、110、95、14、75和62。有2個值散列到第0個槽,1個值散列到第3個槽,3個值散列到第7個槽,1個值散列到第9個槽。

閉散列方法把所有記錄直接存儲在散列表中。每個記錄關鍵碼key有一個由散列函數計算出來的基位置,即h(key)。如果要插入一個關鍵碼,而另一個記錄已經占據了R的基位置(發生碰撞),那麼就把R存儲在表中的其它地址內,由沖突解決策略確定是哪個地址。

閉散列表解決沖突的基本思想是:當沖突發生時,使用某種方法為關鍵碼K生成一個散列地址序列d0,d1,d2,... di ,...dm-1。其中d0=h(K)稱為K的基地址地置( home position );所有di(0< i< m)是後繼散列地址。當插入K時,若基地址上的結點已被別的數據元素佔用,則按上述地址序列依次探查,將找到的第一個開放的空閑位置di作為K的存儲位置;若所有後繼散列地址都不空閑,說明該閉散列表已滿,報告溢出。相應地,檢索K時,將按同值的後繼地址序列依次查找,檢索成功時返回該位置di ;如果沿著探查序列檢索時,遇到了開放的空閑地址,則說明表中沒有待查的關鍵碼。刪除K時,也按同值的後繼地址序列依次查找,查找到某個位置di具有該K值,則刪除該位置di上的數據元素(刪除操作實際上只是對該結點加以刪除標記);如果遇到了開放的空閑地址,則說明表中沒有待刪除的關鍵碼。因此,對於閉散列表來說,構造後繼散列地址序列的方法,也就是處理沖突的方法。

形成探查的方法不同,所得到的解決沖突的方法也不同。下面是幾種常見的構造方法。

(1)線性探測法

將散列表看成是一個環形表,若在基地址d(即h(K)=d)發生沖突,則依次探查下述地址單元:d+1,d+2,......,M-1,0,1,......,d-1直到找到一個空閑地址或查找到關鍵碼為key的結點為止。當然,若沿著該探查序列檢索一遍之後,又回到了地址d,則無論是做插入操作還是做檢索操作,都意味著失敗。 用於簡單線性探查的探查函數是: p(K,i) = i

例9.7 已知一組關鍵碼為(26,36,41,38,44,15,68,12,06,51,25),散列表長度M= 15,用線性探查法解決沖突構造這組關鍵碼的散列表。 因為n=11,利用除余法構造散列函數,選取小於M的最大質數P=13,則散列函數為:h(key) = key%13。按順序插入各個結點: 26: h(26) = 0,36: h(36) = 10, 41: h(41) = 2,38: h(38) = 12, 44: h(44) = 5。 插入15時,其散列地址為2,由於2已被關鍵碼為41的元素佔用,故需進行探查。按順序探查法,顯然3為開放的空閑地址,故可將其放在3單元。類似地,68和12可分別放在4和13單元中.

(2)二次探查法

二次探查法的基本思想是:生成的後繼散列地址不是連續的,而是跳躍式的,以便為後續數據元素留下空間從而減少聚集。二次探查法的探查序列依次為:12,-12,22 ,-22,...等,也就是說,發生沖突時,將同義詞來回散列在第一個地址的兩端。求下一個開放地址的公式為:

(3)隨機探查法

理想的探查函數應當在探查序列中隨機地從未訪問過的槽中選擇下一個位置,即探查序列應當是散列表位置的一個隨機排列。但是,我們實際上不能隨機地從探查序列中選擇一個位置,因為在檢索關鍵碼的時候不能建立起同樣的探查序列。然而,我們可以做一些類似於偽隨機探查( pseudo-random probing )的事情。在偽隨機探查中,探查序列中的第i個槽是(h(K) + ri) mod M,其中ri是1到M - 1之間數的「隨機」數序列。所有插入和檢索都使用相同的「隨機」數。探查函數將是 p(K,i) = perm[i - 1], 這里perm是一個長度為M - 1的數組,它包含值從1到M – 1的隨機序列。

例子:
例如,已知哈希表長度m=11,哈希函數為:H(key)= key % 11,則H(47)=3,H(26)=4,H(60)=5,假設下一個關鍵字為69,則H(69)=3,與47沖突。如果用線性探測再散列處理沖突,下一個哈希地址為H1=(3 + 1)% 11 = 4,仍然沖突,再找下一個哈希地址為H2=(3 + 2)% 11 = 5,還是沖突,繼續找下一個哈希地址為H3=(3 + 3)% 11 = 6,此時不再沖突,將69填入5號單元,參圖8.26 (a)。如果用二次探測再散列處理沖突,下一個哈希地址為H1=(3 + 12)% 11 = 4,仍然沖突,再找下一個哈希地址為H2=(3 - 12)% 11 = 2,此時不再沖突,將69填入2號單元,參圖8.26 (b)。如果用偽隨機探測再散列處理沖突,且偽隨機數序列為:2,5,9,……..,則下一個哈希地址為H1=(3 + 2)% 11 = 5,仍然沖突,再找下一個哈希地址為H2=(3 + 5)% 11 = 8,此時不再沖突,將69填入8號單元,參圖8.26 (c)。

(4)雙散列探查法

偽隨機探查和二次探查都能消除基本聚集——即基地址不同的關鍵碼,其探查序列的某些段重疊在一起——的問題。然而,如果兩個關鍵碼散列到同一個基地址,那麼採用這兩種方法還是得到同樣的探查序列,仍然會產生聚集。這是因為偽隨機探查和二次探查產生的探查序列只是基地址的函數,而不是原來關鍵碼值的函數。這個問題稱為二級聚集( secondary clustering )。

為了避免二級聚集,我們需要使得探查序列是原來關鍵碼值的函數,而不是基位置的函數。雙散列探查法利用第二個散列函數作為常數,每次跳過常數項,做線性探查。

熱點內容
密碼按錯三次怎麼辦 發布:2025-02-01 08:00:24 瀏覽:848
傳送門什麼配置好玩 發布:2025-02-01 08:00:17 瀏覽:997
android監聽輸入法狀態 發布:2025-02-01 07:52:44 瀏覽:280
android仿58 發布:2025-02-01 07:52:41 瀏覽:889
ubuntu解壓zip文件 發布:2025-02-01 07:52:39 瀏覽:223
紅色物業競賽視頻腳本 發布:2025-02-01 07:39:56 瀏覽:715
我的世界領域伺服器 發布:2025-02-01 07:30:06 瀏覽:156
線性表有哪兩種存儲結構 發布:2025-02-01 07:30:04 瀏覽:216
坡向壓縮機 發布:2025-02-01 07:09:10 瀏覽:410
夏新手機初始密碼是什麼 發布:2025-02-01 06:58:23 瀏覽:790