⑴ A*搜尋演算法的簡介
速度和精確度之間的選擇前不是靜態的。你可以基於CPU的速度、用於路徑搜索的時間片數、地圖上物體(units)的數量、物體的重要性、組(group)的大小、難度或者其他任何因素來進行動態的選擇。取得動態的折衷的一個方法是,建立一個啟發式函數用於假定通過一個網格空間的最小代價是1,然後建立一個代價函數(cost function)用於測量(scales):
g』(n) = 1 + alpha * ( g(n) – 1 )
如果alpha是0,則改進後的代價函數的值總是1。這種情況下,地形代價被完全忽略,A*工作變成簡單地判斷一個網格可否通過。如果alpha是1,則最初的代價函數將起作用,然後你得到了A*的所有優點。你可以設置alpha的值為0到1的任意值。
你也可以考慮對啟發式函數的返回值做選擇:絕對最小代價或者期望最小代價。例如,如果你的地圖大部分地形是代價為2的草地,其它一些地方是代價為1的道路,那麼你可以考慮讓啟發式函數不考慮道路,而只返回2*距離。
速度和精確度之間的選擇並不是全局的。在地圖上的某些區域,精確度是重要的,你可以基於此進行動態選擇。例如,假設我們可能在某點停止重新計算路徑或者改變方向,則在接近當前位置的地方,選擇一條好的路徑則是更重要的,因此為何要對後續路徑的精確度感到厭煩?或者,對於在地圖上的一個安全區域,最短路徑也許並不十分重要,但是當從一個敵人的村莊逃跑時,安全和速度是最重要的。
在游戲中,路徑潛在地花費了許多存儲空間,特別是當路徑很長並且有很多物體需要尋路時。路徑壓縮,導航點和beacons通過把多個步驟保存為一個較小數據從而減少了空間需求。Waypoints rely on straight-line segments being common so that we have to store only the endpoints, while beacons rely on there being well-known paths calculated beforehand between specially marked places on the map.如果路徑仍然用了許多存儲空間,可以限制路徑長度,這就回到了經典的時間-空間折衷法:為了節省空間,信息可以被丟棄,稍後才重新計算它。
⑵ 搜索演算法中,A演算法A*演算法的區別(急)
A演算法一般指某個搜索演算法的樸素的思路
A*指使用了啟發式搜索之後的演算法,也就是運算速度會快很多,但不一定能保證最後得到最優解
⑶ 排列a的演算法是什麼
計算方法:
(1)排列數公式
排列用符號A(n,m)表示,m≦n。
計算公式是:A(n,m)=n(n-1)(n-2)……(n-m+1)=n!/(n-m)!
此外規定0!=1,n!表示n(n-1)(n-2)…1
例如:6!=6x5x4x3x2x1=720,4!=4x3x2x1=24。
(2)組合數公式
組合用符號C(n,m)表示,m≦n。
公式是:C(n,m)=A(n,m)/m!或C(n,m)=C(n,n-m)。
例如:C(5,2)=A(5,2)/[2!x(5-2)!]=(1x2x3x4x5)/[2x(1x2x3)]=10。
兩個常用的排列基本計數原理及應用:
1、加法原理和分類計數法:
每一類中的每一種方法都可以獨立地完成此任務。兩類不同辦法中的具體方法,互不相同(即分類不重)。完成此任務的任何一種方法,都屬於某一類(即分類不漏)。
2、乘法原理和分步計數法:
任何一步的一種方法都不能完成此任務,必須且只須連續完成這n步才能完成此任務。各步計數相互獨立。只要有一步中所採取的方法不同,則對應的完成此事的方法也不同。
⑷ A*演算法是什麼
A*
(A-Star)演算法是一種靜態路網中求解最短路最有效的方法。
公式表示為: f(n)=g(n)+h(n),
其中f(n) 是從初始點經由節點n到目標點的估價函數,
g(n) 是在狀態空間中從初始節點到n節點的實際代價,
h(n)是從n到目標節點最佳路徑的估計代價。
保證找到最短路徑(最優解的)條件,關鍵在於估價函數h(n)的選取:
估價值h(n)<= n到目標節點的距離實際值,這種情況下,搜索的點數多,搜索范圍大,效率低。但能得到最優解。
如果 估價值>實際值, 搜索的點數少,搜索范圍小,效率高,但不能保證得到最優解
⑸ 簡述aloha演算法和時隙aloha演算法的基本原理和它們之間的區別
純ALOHA演算法的基本思想即只要有數據待發,就可以發送。而時隙ALOHA演算法是將時間分為離散的時間段,每段時間對應一幀,這種方法必須有全局的時間同步。
ALOHA演算法信道吞吐率: S=G.e-2G
時隙ALOHA演算法信道吞吐率: S=G.e-G
⑹ A*演算法的介紹
A*演算法;A*(A-Star)演算法是一種靜態路網中求解最短路徑最有效的直接搜索方法。估價值與實際值越接近,估價函數取得就越好。
⑺ 快速排序演算法原理與實現
快速排序的基本思想就是從一個數組中任意挑選一個元素(通常來說會選擇最左邊的元素)作為中軸元素,將剩下的元素以中軸元素作為比較的標准,將小於等於中軸元素的放到中軸元素的左邊,將大於中軸元素的放到中軸元素的右邊。
然後以當前中軸元素的位置為界,將左半部分子數組和右半部分子數組看成兩個新的數組,重復上述操作,直到子數組的元素個數小於等於1(因為一個元素的數組必定是有序的)。
以下的代碼中會常常使用交換數組中兩個元素值的Swap方法,其代碼如下
publicstaticvoidSwap(int[] A, inti, intj){
inttmp;
tmp = A[i];
A[i] = A[j];
A[j] = tmp;
(7)簡述A演算法實現的基本原理擴展閱讀:
快速排序演算法 的基本思想是:將所要進行排序的數分為左右兩個部分,其中一部分的所有數據都比另外一 部分的數據小,然後將所分得的兩部分數據進行同樣的劃分,重復執行以上的劃分操作,直 到所有要進行排序的數據變為有序為止。
定義兩個變數low和high,將low、high分別設置為要進行排序的序列的起始元素和最後一個元素的下標。第一次,low和high的取值分別為0和n-1,接下來的每次取值由劃分得到的序列起始元素和最後一個元素的下標來決定。
定義一個變數key,接下來以key的取值為基準將數組A劃分為左右兩個部分,通 常,key值為要進行排序序列的第一個元素值。第一次的取值為A[0],以後毎次取值由要劃 分序列的起始元素決定。
從high所指向的數組元素開始向左掃描,掃描的同時將下標為high的數組元素依次與劃分基準值key進行比較操作,直到high不大於low或找到第一個小於基準值key的數組元素,然後將該值賦值給low所指向的數組元素,同時將low右移一個位置。
如果low依然小於high,那麼由low所指向的數組元素開始向右掃描,掃描的同時將下標為low的數組元素值依次與劃分的基準值key進行比較操作,直到low不小於high或找到第一個大於基準值key的數組元素,然後將該值賦給high所指向的數組元素,同時將high左移一個位置。
重復步驟(3) (4),直到low的植不小於high為止,這時成功劃分後得到的左右兩部分分別為A[low……pos-1]和A[pos+1……high],其中,pos下標所對應的數組元素的值就是進行劃分的基準值key,所以在劃分結束時還要將下標為pos的數組元素賦值 為 key。
⑻ 請教一個演算法的實現原理
快速排序是對冒泡排序的一種改進。它的基本思想是:通過一躺排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一不部分的所有數據都要小,然後再按次方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
假設要排序的數組是A[1]……A[N],首先任意選取一個數據(通常選用第一個數據)作為關鍵數據,然後將所有比它的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一躺快速排序。一躺快速排序的演算法是:
1)、設置兩個變數I、J,排序開始的時候I:=1,J:=N;
2)以第一個數組元素作為關鍵數據,賦值給X,即X:=A[1];
3)、從J開始向前搜索,即由後開始向前搜索(J:=J-1),找到第一個小於X的值,兩者交換;
4)、從I開始向後搜索,即由前開始向後搜索(I:=I+1),找到第一個大於X的值,兩者交換;
5)、重復第3、4步,直到I=J;
例如:待排序的數組A的值分別是:(初始關鍵數據X:=49)
A[1] A[2] A[3] A[4] A[5] A[6] A[7]:
49 38 65 97 76 13 27
進行第一次交換後: 27 38 65 97 76 13 49
( 按照演算法的第三步從後面開始找
進行第二次交換後: 27 38 49 97 76 13 65
( 按照演算法的第四步從前面開始找>X的值,65>49,兩者交換,此時I:=3 )
進行第三次交換後: 27 38 13 97 76 49 65
( 按照演算法的第五步將又一次執行演算法的第三步從後開始找
進行第四次交換後: 27 38 13 49 76 97 65
( 按照演算法的第四步從前面開始找大於X的值,97>49,兩者交換,此時J:=4 )
此時再執行第三不的時候就發現I=J,從而結束一躺快速排序,那麼經過一躺快速排序之後的結果是:27 38 13 49 76 97 65,即所以大於49的數全部在49的後面,所以小於49的數全部在49的前面。
快速排序就是遞歸調用此過程——在以49為中點分割這個數據序列,分別對前面一部分和後面一部分進行類似的快速排序,從而完成全部數據序列的快速排序,最後把此數據序列變成一個有序的序列,根據這種思想對於上述數組A的快速排序的全過程如圖6所示:
初始狀態 {49 38 65 97 76 13 27}
進行一次快速排序之後劃分為 {27 38 13} 49 {76 97 65}
分別對前後兩部分進行快速排序 {13} 27 {38}
結束 結束 {49 65} 76 {97}
49 {65} 結束
結束
圖6 快速排序全過程
1)、設有N(假設N=10)個數,存放在S數組中;
2)、在S[1。。N]中任取一個元素作為比較基準,例如取T=S[1],起目的就是在定出T應在排序結果中的位置K,這個K的位置在:S[1。。K-1]<=S[K]<=S[K+1..N],即在S[K]以前的數都小於S[K],在S[K]以後的數都大於S[K];
3)、利用分治思想(即大化小的策略)可進一步對S[1。。K-1]和S[K+1。。N]兩組數據再進行快速排序直到分組對象只有一個數據為止。
如具體數據如下,那麼第一躺快速排序的過程是:
數組下標: 1 2 3 4 5 6 7 8 9 10
45 36 18 53 72 30 48 93 15 36
I J
(1) 36 36 18 53 72 30 48 93 15 45
(2) 36 36 18 45 72 30 48 93 15 53
(3) 36 36 18 15 72 30 48 93 45 53
(4) 36 36 18 15 45 30 48 93 72 53
(5) 36 36 18 15 30 45 48 93 72 53
通過一躺排序將45放到應該放的位置K,這里K=6,那麼再對S[1。。5]和S[6。。10]分別進行快速排序。
一般來說,冒泡法是程序員最先接觸的排序方法,它的優點是原理簡單,編程實現容易,但它的缺點就是--程序的大忌--速度太慢。下面我介紹一個理解上簡單但編程實現上不是太容易的排序方法,我不知道它是不是現有排序方法中最快的,但它是我見過的最快的。排序同樣的數組,它所需的時間只有冒泡法的 4% 左右。我暫時稱它為「快速排序法」。
「快速排序法」使用的是遞歸原理,下面我結合一個例子來說明「快速排序法」的原理。首先給出一個數組{53,12,98,63,18,72,80,46, 32,21},先找到第一個數--53,把它作為中間值,也就是說,要把53放在一個位置,使得它左邊的值比它小,右邊的值比它大。{21,12,32, 46,18,53,80,72,63,98},這樣一個數組的排序就變成了兩個小數組的排序--53左邊的數組和53右邊的數組,而這兩個數組繼續用同樣的方式繼續下去,一直到順序完全正確。
我這樣講你們是不是很胡塗,不要緊,我下面給出實現的兩個函數:
/*
n就是需要排序的數組,left和right是你需要排序的左界和右界,
如果要排序上面那個數組,那麼left和right分別是0和9
*/
void quicksort(int n[], int left,int right)
{
int dp;
if (left<right) {
/*
這就是下面要講到的函數,按照上面所說的,就是把所有小於53的數放
到它的左邊,大的放在右邊,然後返回53在整理過的數組中的位置。
*/
dp=partition(n,left,right);
quicksort(n,left,dp-1);
quicksort(n,dp+1,right); //這兩個就是遞歸調用,分別整理53左邊的數組和右邊的數組
}
}
我們上面提到先定位第一個數,然後整理這個數組,把比這個數小的放到它的左邊,大的放右邊,然後
返回這中間值的位置,下面這函數就是做這個的。
int partition(int n[],int left,int right)
{
int lo,hi,pivot,t;
pivot=n[left];
lo=left-1;
hi=right+1;
while(lo+1!=hi) {
if(n[lo+1]<=pivot)
lo++;
else if(n[hi-1]>pivot)
hi--;
else {
t=n[lo+1];
n[++lo]=n[hi-1];
n[--hi]=t;
}
}
n[left]=n[lo];
n[lo]=pivot;
return lo;
}
這段程序並不難,應該很好看懂,我把過程大致講一下,首先你的腦子里先浮現一個數組和三個指針,第一個指針稱為p指針,在整個過程結束之前它牢牢的指向第一個數,第二個指針和第三個指針分別為lo指針和hi指針,分別指向最左邊的值和最右邊的值。lo指針和hi指針從兩邊同時向中間逼近,在逼近的過程中不停的與p指針的值比較,如果lo指針的值比p指針的值小,lo++,還小還++,再小再++,直到碰到一個大於p指針的值,這時視線轉移到hi指針,如果 hi指針的值比p指針的值大,hi--,還大還--,再大再--,直到碰到一個小於p指針的值。這時就把lo指針的值和hi指針的值做一個調換。持續這過程直到兩個指針碰面,這時把p指針的值和碰面的值做一個調換,然後返回p指針新的
⑼ A*演算法應用,大家給點介紹,做課程設計
維基網路有很多的,大陸訪問不了,可以設置個香港代理。
SHA 家族
[編輯首段]維基網路,自由的網路全書
跳轉到: 導航, 搜尋
安全散列演演演算法能計算出一個數位訊息所對應到的,長度固定的字串(又稱訊息摘要)。且若輸入的訊息不同,它們對應到不同字串的機率很高;而 SHA 是FIPS所認證的五種安全雜湊演演演算法。這些演演演算法之所以稱作「安全」是基於以下兩點(根據官方標準的描述):「1)由訊息摘要反推原輸入訊息,從計算理論上來說是很困難的。2)想要找到兩組不同的訊息對應到相同的訊息摘要,從計算理論上來說也是很困難的。任何對輸入訊息的變動,都有很高的機率導致其產生的訊息摘要迥異。」
SHA 家族的五個演演演算法,分別是SHA-1, SHA-224, SHA-256, SHA-384, 和 SHA-512,由美國國家安全局 (NSA) 所設計,並由美國國家標准與技術研究院(NIST) 發布;是美國的政府標准。後四者有時並稱為SHA-2。SHA-1 在許多安全協定中廣為使用,包括 TLS 和 SSL、 PGP、SSH、S/MIME 和 IPsec,曾被視為是 MD5(更早之前被廣為使用的雜湊函數)的後繼者。但 SHA-1 的安全性如今被密碼學家嚴重質疑;雖然至今尚未出現對 SHA-2 有效的攻擊,它的演演演算法跟 SHA-1 基本上仍然相似;因此有些人開始發展其他替代的雜湊演演演算法。緣於最近對 SHA-1 的種種攻擊發表,「美國國家標准與技術研究院(NIST)開始設法經由公開競爭管道(類似高級加密標准AES的發展經過),發展一個或多個新的雜湊演演演算法。」
目錄 [隱藏]
1 SHA-0 和 SHA-1
1.1 SHA-0 的破解
1.2 SHA-1 的破解
2 SHA-2
3 SHA 所定義的長度
4 SHAd
5 應用
6 SHA-1 演演演算法
7 SHA-2 演演演算法
8 參見
9 參考資料
10 外部鏈結
[編輯] SHA-0 和 SHA-1
SHA-1 壓縮演演演算法中的一個迴圈。A, B, C, D 和 E 是這個state中的 32 位元文字;F 是會變化的非線性函數;<<<n 代表bit向左循環移動n個位置。n因操作而異。田代表molo 232之下的加法,Kt 是一個常數。最初載明的演演演算法於 1993年發布,稱做安全雜湊標准 (Secure Hash Standard),FIPS PUB 180。這個版本現在常被稱為 SHA-0。它在發布之後很快就被 NSA 撤回,並且由 1995年發布的修訂版本 FIPS PUB 180-1 (通常稱為 SHA-1) 取代。SHA-1 和 SHA-0 的演演演算法只在壓縮函數的訊息轉換部份差了一個位元的循環位移。根據 NSA 的說法,它修正了一個在原始演演演算法中會降低密碼安全性的錯誤。然而 NSA 並沒有提供任何進一步的解釋或證明該錯誤已被修正。而後 SHA-0 和 SHA-1 的弱點相繼被攻破,SHA-1 似乎是顯得比 SHA-0 有抵抗性,這多少證實了 NSA 當初修正演演演算法以增進安全性的聲明。
SHA-0 和 SHA-1 可將一個最大 264 位元的訊息,轉換成一串 160 位元的訊息摘要;其設計原理相似於 MIT 教授 Ronald L. Rivest 所設計的密碼學雜湊演演演算法 MD4 和 MD5。
[編輯] SHA-0 的破解
在 CRYPTO 98 上,兩位法國研究者提出一種對 SHA-0 的攻擊方式 (Chabaud and Joux, 1998): 在 261的計算復雜度之內,就可以發現一次碰撞(即兩個不同的訊息對應到相同的訊息摘要);這個數字小於 280 ,也就是說,其安全性不到一個理想的雜湊函數抵抗攻擊所應具備的計算復雜度。
2004年時,Biham 和 Chen 也發現了 SHA-0 的近似碰撞 — 兩個訊息可以雜湊出幾乎相同的數值;其中 162 位元中有 142 位元相同。他們也發現了 SHA-0 的完整碰撞(相對於近似碰撞),將本來需要 80 次方的復雜度降低到 62 次方。
2004年8月12日,Joux, Carribault, Lemuet 和 Jalby 宣布找到 SHA-0 演演演算法的完整碰撞的方法,這是歸納 Chabaud 和 Joux 的攻擊所完成的結果。發現一個完整碰撞只需要 251的計算復雜度。他們使用的是一台有 256 顆 Itanium2 處理器的超級電腦,約耗 80,000 CPU 工時 [1]。
2004年8月17日,在 CRYPTO 2004 的 Rump 會議上,王小雲, 馮登國 (Feng), 來學嘉 (Lai), 和於紅波 (Yu) 宣布了攻擊 MD5、SHA-0 和其他雜湊函數的初步結果。他們攻擊 SHA-0 的計算復雜度是 240,這意謂的他們的攻擊成果比 Joux 還有其他人所做的更好。請參見 MD5 安全性。2005 年二月,王小雲和殷益群、於紅波再度發表了對 SHA-0 破密的演演演算法,可在 239 的計算復雜度內就找到碰撞。
[編輯] SHA-1 的破解
鑒於 SHA-0 的破密成果,專家們建議那些計畫利用 SHA-1 實作密碼系統的人們也應重新考慮。2004 年 CRYPTO 會議結果公布之後,NIST 即宣布他們將逐漸減少使用 SHA-1,改以 SHA-2 取而代之。
2005年,Rijmen 和 Oswald 發表了對 SHA-1 較弱版本(53次的加密迴圈而非80次)的攻擊:在 280 的計算復雜度之內找到碰撞。
2005年二月,王小雲、殷益群及於紅波發表了對完整版 SHA-1 的攻擊,只需少於 269 的計算復雜度,就能找到一組碰撞。(利用暴力搜尋法找到碰撞需要 280 的計算復雜度。)
這篇論文的作者們寫道;「我們的破密分析是以對付 SHA-0 的差分攻擊、近似碰撞、多區塊碰撞技術、以及從 MD5 演演演算法中尋找碰撞的訊息更改技術為基礎。沒有這些強力的分析工具,SHA-1 就無法破解。」此外,作者還展示了一次對 58 次加密迴圈 SHA-1 的破密,在 233 個單位操作內就找到一組碰撞。完整攻擊方法的論文發表在 2005 年八月的 CRYPTO 會議中。
殷益群在一次面談中如此陳述:「大致上來說,我們找到了兩個弱點:其一是前置處理不夠復雜;其二是前 20 個迴圈中的某些數學運算會造成不可預期的安全性問題。」
2005 年八月 17 的 CRYPTO 會議尾聲中王小雲、姚期智、姚儲楓再度發表更有效率的 SHA-1 攻擊法,能在 263 個計算復雜度內找到碰撞。
在密碼學的學術理論中,任何攻擊方式,其計算復雜度若少於暴力搜尋法所需要的計算復雜度,就能被視為針對該密碼系統的一種破密法;這並不表示該破密法已經可以進入實際應用的階段。
就應用層面的考量而言,一種新的破密法出現,暗示著將來可能會出現更有效率、足以實用的改良版本。雖然這些實用的破密法版本根本還沒誕生,但確有必要發展更強的雜湊演演演算法來取代舊的演演演算法。在「碰撞」攻擊法之外,另有一種反譯攻擊法,就是由雜湊出的字串反推原本的訊息;反譯攻擊的嚴重性更在碰撞攻擊之上。 在許多會應用到密碼雜湊的情境(如用戶密碼的存放、文件的數位簽章等)中,碰撞攻擊的影響並不是很大。舉例來說,一個攻擊者可能不會只想要偽造一份一模一樣的文件,而會想改造原來的文件,再附上合法的簽章,來愚弄持有私密金鑰的驗證者。另一方面,如果可以從密文中反推未加密前的使用者密碼,攻擊者就能利用得到的密碼登入其他使用者的帳戶,而這種事在密碼系統中是不能被允許的。但若存在反譯攻擊,只要能得到指定使用者密碼雜湊過後的字串(通常存在影檔中,而且可能不會透露原密碼資訊),就有可能得到該使用者的密碼。
2006 年的 CRYPTO 會議上,Christian Rechberger 和 Christophe De Cannière 宣布他們能在容許攻擊者決定部分原訊息的條件之下,找到 SHA-1 的一個碰撞。
[編輯] SHA-2
SHA-2 的第t個加密迴圈。圖中的深藍色方塊是事先定義好的非線性函數。ABCDEFGH一開始分別是八個初始值,Kt是第t個金鑰,Wt是本區塊產生第t個word。原訊息被切成固定長度的區塊,對每一個區塊,產生n個word(n視演演演算法而定),透過重復運作迴圈n次對ABCDEFGH這八個工作區段循環加密。最後一次迴圈所產生的八段字串合起來即是此區塊對應到的雜湊字串。若原訊息包含數個區塊,則最後還要將這些區塊產生的雜湊字串加以混合才能產生最後的雜湊字串。NIST 發布了三個額外的 SHA 變體,這三個函數都將訊息對應到更長的訊息摘要。以它們的摘要長度 (以位元計算) 加在原名後面來命名:SHA-256,SHA-384 和 SHA-512。它們發布於 2001年的 FIPS PUB 180-2 草稿中,隨即通過審查和評論。包含 SHA-1 的 FIPS PUB 180-2,於 2002年以官方標准發布。2004年2月,發布了一次 FIPS PUB 180-2 的變更通知,加入了一個額外的變種 "SHA-224",這是為了符合雙金鑰 3DES 所需的金鑰長度而定義。
SHA-256 和 SHA-512 是很新的雜湊函數,前者以定義一個word為32位元,後者則定義一個word為64位元。它們分別使用了不同的偏移量,或用不同的常數,然而,實際上二者結構是相同的,只在迴圈執行的次數上有所差異。 SHA-224 以及 SHA-384 則是前述二種雜湊函數的截短版,利用不同的初始值做計算。
這些新的雜湊函數並沒有接受像 SHA-1 一樣的公眾密碼社群做詳細的檢驗,所以它們的密碼安全性還不被大家廣泛的信任。Gilbert 和 Handschuh (2003) 曾對這些新變種作過一些研究,聲稱他們沒有弱點。
[編輯] SHA 所定義的長度
下表中的中繼雜湊值(internal state)表示對每個資料區塊壓縮雜湊過後的中繼值(internal hash sum)。詳情請參見Merkle-Damgård construction。
演演演算法 輸出雜湊值長度 (bits) 中繼雜湊值長度 (bits) 資料區塊長度 (bits) 最大輸入訊息長度 (bits) 一個Word長度 (bits) 迴圈次數 使用到的運運算元 碰撞攻擊
SHA-0 160 160 512 264 − 1 32 80 +,and,or,xor,rotl 是
SHA-1 160 160 512 264 − 1 32 80 +,and,or,xor,rotl 存在263 的攻擊
SHA-256/224 256/224 256 512 264 − 1 32 64 +,and,or,xor,shr,rotr 尚未出現
SHA-512/384 512/384 512 1024 2128 − 1 64 80 +,and,or,xor,shr,rotr 尚未出現
[編輯] SHAd
SHAd 函數是一個簡單的相同 SHA 函數的重述:
SHAd-256(m)=SHA-256(SHA-256(m))。它會克服有關延伸長度攻擊的問題。
[編輯] 應用
SHA-1, SHA-224, SHA-256, SHA-384 和 SHA-512 都被需要安全雜湊演演演算法的美國聯邦政府所應用,他們也使用其他的密碼演演演算法和協定來保護敏感的未保密資料。FIPS PUB 180-1 也鼓勵私人或商業組織使用 SHA-1 加密。Fritz-chip 將很可能使用 SHA-1 雜湊函數來實現個人電腦上的數位版權管理。
首先推動安全雜湊演演演算法出版的是已合並的數位簽章標准。
SHA 雜湊函數已被做為 SHACAL 分組密碼演演演算法的基礎。
[編輯] SHA-1 演演演算法
以下是 SHA-1 演演演算法的虛擬碼:
Note: All variables are unsigned 32 bits and wrap molo 232 when calculating
Initialize variables:
h0 := 0x67452301
h1 := 0xEFCDAB89
h2 := 0x98BADCFE
h3 := 0x10325476
h4 := 0xC3D2E1F0
Pre-processing:
append the bit '1' to the message
append k bits '0', where k is the minimum number >= 0 such that the resulting message
length (in bits) is congruent to 448 (mod 512)
append length of message (before pre-processing), in bits, as 64-bit big-endian integer
Process the message in successive 512-bit chunks:
break message into 512-bit chunks
for each chunk
break chunk into sixteen 32-bit big-endian words w[i], 0 ≤ i ≤ 15
Extend the sixteen 32-bit words into eighty 32-bit words:
for i from 16 to 79
w[i] := (w[i-3] xor w[i-8] xor w[i-14] xor w[i-16]) leftrotate 1
Initialize hash value for this chunk:
a := h0
b := h1
c := h2
d := h3
e := h4
Main loop:
for i from 0 to 79
if 0 ≤ i ≤ 19 then
f := (b and c) or ((not b) and d)
k := 0x5A827999
else if 20 ≤ i ≤ 39
f := b xor c xor d
k := 0x6ED9EBA1
else if 40 ≤ i ≤ 59
f := (b and c) or (b and d) or (c and d)
k := 0x8F1BBCDC
else if 60 ≤ i ≤ 79
f := b xor c xor d
k := 0xCA62C1D6
temp := (a leftrotate 5) + f + e + k + w[i]
e := d
d := c
c := b leftrotate 30
b := a
a := temp
Add this chunk's hash to result so far:
h0 := h0 + a
h1 := h1 + b
h2 := h2 + c
h3 := h3 + d
h4 := h4 + e
Proce the final hash value (big-endian):
digest = hash = h0 append h1 append h2 append h3 append h4
上述關於 f 運算式列於 FIPS PUB 180-1 中 , 以下替代運算式也許也能在主要迴圈裡計算 f :
(0 ≤ i ≤ 19): f := d xor (b and (c xor d)) (alternative)
(40 ≤ i ≤ 59): f := (b and c) or (d and (b or c)) (alternative 1)
(40 ≤ i ≤ 59): f := (b and c) or (d and (b xor c)) (alternative 2)
(40 ≤ i ≤ 59): f := (b and c) + (d and (b xor c)) (alternative 3)
[編輯] SHA-2 演演演算法
以下是SHA-256 演演演算法的虛擬碼。注意,64個word w[16..63]中的位元比起 SHA-1 演演演算法,混合的程度大幅提升。
Note: All variables are unsigned 32 bits and wrap molo 232 when calculating
Initialize variables
(first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
h0 := 0x6a09e667
h1 := 0xbb67ae85
h2 := 0x3c6ef372
h3 := 0xa54ff53a
h4 := 0x510e527f
h5 := 0x9b05688c
h6 := 0x1f83d9ab
h7 := 0x5be0cd19
Initialize table of round constants
(first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
k[0..63] :=
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
Pre-processing:
append the bit '1' to the message
append k bits '0', where k is the minimum number >= 0 such that the resulting message
length (in bits) is congruent to 448 (mod 512)
append length of message (before pre-processing), in bits, as 64-bit big-endian integer
Process the message in successive 512-bit chunks:
break message into 512-bit chunks
for each chunk
break chunk into sixteen 32-bit big-endian words w[0..15]
Extend the sixteen 32-bit words into sixty-four 32-bit words:
for i from 16 to 63
s0 := (w[i-15] rightrotate 7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift 3)
s1 := (w[i-2] rightrotate 17) xor (w[i-2] rightrotate 19) xor (w[i-2] rightshift 10)
w[i] := w[i-16] + s0 + w[i-7] + s1
Initialize hash value for this chunk:
a := h0
b := h1
c := h2
d := h3
e := h4
f := h5
g := h6
h := h7
Main loop:
for i from 0 to 63
s0 := (a rightrotate 2) xor (a rightrotate 13) xor (a rightrotate 22)
maj := (a and b) xor (a and c) xor (b and c)
t2 := s0 + maj
s1 := (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate 25)
ch := (e and f) xor ((not e) and g)
t1 := h + s1 + ch + k[i] + w[i]
h := g
g := f
f := e
e := d + t1
d := c
c := b
b := a
a := t1 + t2
Add this chunk's hash to result so far:
h0 := h0 + a
h1 := h1 + b
h2 := h2 + c
h3 := h3 + d
h4 := h4 + e
h5 := h5 + f
h6 := h6 + g
h7 := h7 + h
Proce the final hash value (big-endian):
digest = hash = h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7
其中 ch 函數及 maj 函數可利用前述 SHA-1 的優化方式改寫。
SHA-224 和 SHA-256 基本上是相同的, 除了:
h0 到 h7 的初始值不同,以及
SHA-224 輸出時截掉 h7 的函數值。
SHA-512 和 SHA-256 的結構相同,但:
SHA-512 所有的數字都是64位元,
SHA-512 執行80次加密迴圈而非64次,
SHA-512 初始值和常數拉長成64位元,以及
二者位元的偏移量和循環位移量不同。
SHA-384 和 SHA-512 基本上是相同的,除了:
h0 到 h7 的初始值不同,以及
SHA-384 輸出時截掉 h6 和 h7 的函數值。