當前位置:首頁 » 操作系統 » a演算法的應用

a演算法的應用

發布時間: 2022-08-17 01:58:26

『壹』 A*演算法用於路徑規劃,有什麼缺點

缺點:A*演算法通過比較當前路徑柵格的8個鄰居的啟發式函數值F來逐步確定下一個路徑柵格,當存在多個最小值時A*演算法不能保證搜索的路徑最優。
A*演算法;A*(A-Star)演算法是一種靜態路網中求解最短路徑最有效的直接搜索方法。估價值與實際值越接近,估價函數取得就越好。A*[1] (A-Star)演算法是一種靜態路網中求解最短路最有效的直接搜索方法。注意是最有效的直接搜索演算法。之後涌現了很多預處理演算法(ALT,CH,HL等等),在線查詢效率是A*演算法的數千甚至上萬倍。公式表示為: f(n)=g(n)+h(n),其中 f(n) 是從初始點經由節點n到目標點的估價函數,g(n) 是在狀態空間中從初始節點到n節點的實際代價,h(n) 是從n到目標節點最佳路徑的估計代價。保證找到最短路徑(最優解的)條件,關鍵在於估價函數f(n)的選取:估價值h(n)<= n到目標節點的距離實際值,這種情況下,搜索的點數多,搜索范圍大,效率低。但能得到最優解。並且如果h(n)=d(n),即距離估計h(n)等於最短距離,那麼搜索將嚴格沿著最短路徑進行, 此時的搜索效率是最高的。如果 估價值>實際值,搜索的點數少,搜索范圍小,效率高,但不能保證得到最優解。

『貳』 誰能介紹一下游戲編程中著名的A演算法

全書由三部分組成。其中第一部分主要介紹游戲編程的基本概念;第二部分詳細介紹游戲編程中的各種技術和演算法;第三部分是附錄,介紹游戲編程中相關技術和知識以及其他相關讀物。第1章 游戲編程時間表1.1 第一階段:「星球大戰」之前1.2 第二階段:...

『叄』 排列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*演算法:A*(A-Star)演算法是一種靜態路網中求解最短路徑最有效的直接搜索方法。估價值與實際值越接近,估價函數取得就越好
A* (A-Star)演算法是一種靜態路網中求解最短路最有效的直接搜索方法。
注意是最有效的直接搜索演算法。之後涌現了很多預處理演算法(ALT,CH,HL等等),在線查詢效率是A*演算法的數千甚至上萬倍。
公式表示為: f(n)=g(n)+h(n),
其中 f(n) 是從初始點經由節點n到目標點的估價函數,
g(n) 是在狀態空間中從初始節點到n節點的實際代價,
h(n) 是從n到目標節點最佳路徑的估計代價。
保證找到最短路徑(最優解的)條件,關鍵在於估價函數f(n)的選取:
估價值h(n)<= n到目標節點的距離實際值,這種情況下,搜索的點數多,搜索范圍大,效率低。但能得到最優解。並且如果h(n)=d(n),即距離估計h(n)等於最短距離,那麼搜索將嚴格沿著最短路徑進行, 此時的搜索效率是最高的。
如果 估價值>實際值,搜索的點數少,搜索范圍小,效率高,但不能保證得到最優解。

『伍』 A*演算法的實際運用

估價值與實際值越接近,估價函數取得就越好
例如對於幾何路網來說,可以取兩節點間曼哈頓距離做為估價值,即f=g(n) + (abs(dx - nx) + abs(dy - ny));這樣估價函數f在g值一定的情況下,會或多或少的受估價值h的制約,節點距目標點近,h值小,f值相對就小,能保證最短路的搜索向終點的方向進行。明顯優於Dijkstra演算法的毫無方向的向四周搜索。
conditions of heuristic
Optimistic (must be less than or equal to the real cost)
As close to the real cost as possible
詳細內容:
創建兩個表,OPEN表保存所有已生成而未考察的節點,CLOSED表中記錄已訪問過的節點。
算起點的估價值;
將起點放入OPEN表; while(OPEN!=NULL){從OPEN表中取估價值f(n)最小的節點n;if(n節點==目標節點)break;for(當前節點n的每個子節點X){算X的估價值;if(XinOPEN)if(X的估價值小於OPEN表的估價值){把n設置為X的父親;更新OPEN表中的估價值;//取最小路徑的估價值}if(XinCLOSE)continue;if(Xnotinboth){把n設置為X的父親;求X的估價值;並將X插入OPEN表中;//還沒有排序}}//endfor將n節點插入CLOSE表中;按照估價值將OPEN表中的節點排序;//實際上是比較OPEN表內節點f的大小,從最小路徑的節點向下進行。}//endwhile(OPEN!=NULL)保存路徑,即從終點開始,每個節點沿著父節點移動直至起點,這就是你的路徑;
用C語言實現A*最短路徑搜索演算法 ,作者 Tittup frog(跳跳蛙)。 #include<stdio.h>#include<math.h>#defineMaxLength100//用於優先隊列(Open表)的數組#defineHeight15//地圖高度#defineWidth20//地圖寬度#defineReachable0//可以到達的結點#defineBar1//障礙物#definePass2//需要走的步數#defineSource3//起點#defineDestination4//終點#defineSequential0//順序遍歷#defineNoSolution2//無解決方案#defineInfinity0xfffffff#defineEast(1<<0)#defineSouth_East(1<<1)#defineSouth(1<<2)#defineSouth_West(1<<3)#defineWest(1<<4)#defineNorth_West(1<<5)#defineNorth(1<<6)#defineNorth_East(1<<7)typedefstruct{signedcharx,y;}Point;constPointdir[8]={{0,1},//East{1,1},//South_East{1,0},//South{1,-1},//South_West{0,-1},//West{-1,-1},//North_West{-1,0},//North{-1,1}//North_East};unsignedcharwithin(intx,inty){return(x>=0&&y>=0&&x<Height&&y<Width);}typedefstruct{intx,y;unsignedcharreachable,sur,value;}MapNode;typedefstructClose{MapNode*cur;charvis;structClose*from;floatF,G;intH;}Close;typedefstruct//優先隊列(Open表){intlength;//當前隊列的長度Close*Array[MaxLength];//評價結點的指針}Open;staticMapNodegraph[Height][Width];staticintsrcX,srcY,dstX,dstY;//起始點、終點staticCloseclose[Height][Width];//優先隊列基本操作voidinitOpen(Open*q)//優先隊列初始化{q->length=0;//隊內元素數初始為0}voidpush(Open*q,Closecls[Height][Width],intx,inty,floatg){//向優先隊列(Open表)中添加元素Close*t;inti,mintag;cls[x][y].G=g;//所添加節點的坐標cls[x][y].F=cls[x][y].G+cls[x][y].H;q->Array[q->length++]=&(cls[x][y]);mintag=q->length-1;for(i=0;i<q->length-1;i++){if(q->Array[i]->F<q->Array[mintag]->F){mintag=i;}}t=q->Array[q->length-1];q->Array[q->length-1]=q->Array[mintag];q->Array[mintag]=t;//將評價函數值最小節點置於隊頭}Close*shift(Open*q){returnq->Array[--q->length];}//地圖初始化操作voidinitClose(Closecls[Height][Width],intsx,intsy,intdx,intdy){//地圖Close表初始化配置inti,j;for(i=0;i<Height;i++){for(j=0;j<Width;j++){cls[i][j].cur=&graph[i][j];//Close表所指節點cls[i][j].vis=!graph[i][j].reachable;//是否被訪問cls[i][j].from=NULL;//所來節點cls[i][j].G=cls[i][j].F=0;cls[i][j].H=abs(dx-i)+abs(dy-j);//評價函數值}}cls[sx][sy].F=cls[sx][sy].H;//起始點評價初始值//cls[sy][sy].G=0;//移步花費代價值cls[dx][dy].G=Infinity;}voidinitGraph(constintmap[Height][Width],intsx,intsy,intdx,intdy){//地圖發生變化時重新構造地inti,j;srcX=sx;//起點X坐標srcY=sy;//起點Y坐標dstX=dx;//終點X坐標dstY=dy;//終點Y坐標for(i=0;i<Height;i++){for(j=0;j<Width;j++){graph[i][j].x=i;//地圖坐標Xgraph[i][j].y=j;//地圖坐標Ygraph[i][j].value=map[i][j];graph[i][j].reachable=(graph[i][j].value==Reachable);//節點可到達性graph[i][j].sur=0;//鄰接節點個數if(!graph[i][j].reachable){continue;}if(j>0){if(graph[i][j-1].reachable)//left節點可以到達{graph[i][j].sur|=West;graph[i][j-1].sur|=East;}if(i>0){if(graph[i-1][j-1].reachable&&graph[i-1][j].reachable&&graph[i][j-1].reachable)//up-left節點可以到達{graph[i][j].sur|=North_West;graph[i-1][j-1].sur|=South_East;}}}if(i>0){if(graph[i-1][j].reachable)//up節點可以到達{graph[i][j].sur|=North;graph[i-1][j].sur|=South;}if(j<Width-1){if(graph[i-1][j+1].reachable&&graph[i-1][j].reachable&&map[i][j+1]==Reachable)//up-right節點可以到達{graph[i][j].sur|=North_East;graph[i-1][j+1].sur|=South_West;}}}}}}intbfs(){inttimes=0;inti,curX,curY,surX,surY;unsignedcharf=0,r=1;Close*p;Close*q[MaxLength]={&close[srcX][srcY]};initClose(close,srcX,srcY,dstX,dstY);close[srcX][srcY].vis=1;while(r!=f){p=q[f];f=(f+1)%MaxLength;curX=p->cur->x;curY=p->cur->y;for(i=0;i<8;i++){if(!(p->cur->sur&(1<<i))){continue;}surX=curX+dir[i].x;surY=curY+dir[i].y;if(!close[surX][surY].vis){close[surX][surY].from=p;close[surX][surY].vis=1;close[surX][surY].G=p->G+1;q[r]=&close[surX][surY];r=(r+1)%MaxLength;}}times++;}returntimes;}intastar(){//A*演算法遍歷//inttimes=0;inti,curX,curY,surX,surY;floatsurG;Openq;//Open表Close*p;initOpen(&q);initClose(close,srcX,srcY,dstX,dstY);close[srcX][srcY].vis=1;push(&q,close,srcX,srcY,0);while(q.length){//times++;p=shift(&q);curX=p->cur->x;curY=p->cur->y;if(!p->H){returnSequential;}for(i=0;i<8;i++){if(!(p->cur->sur&(1<<i))){continue;}surX=curX+dir[i].x;surY=curY+dir[i].y;if(!close[surX][surY].vis){close[surX][surY].vis=1;close[surX][surY].from=p;surG=p->G+sqrt((curX-surX)*(curX-surX)+(curY-surY)*(curY-surY));push(&q,close,surX,surY,surG);}}}//printf(times:%d ,times);returnNoSolution;//無結果}constintmap[Height][Width]={{0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,1},{0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1},{0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,1},{0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1},{0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},{0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0},{0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1},{0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0}};constcharSymbol[5][3]={□,▓,▽,☆,◎};voidprintMap(){inti,j;for(i=0;i<Height;i++){for(j=0;j<Width;j++){printf(%s,Symbol[graph[i][j].value]);}puts();}puts();}Close*getShortest(){//獲取最短路徑intresult=astar();Close*p,*t,*q=NULL;switch(result){caseSequential://順序最近p=&(close[dstX][dstY]);while(p)//轉置路徑{t=p->from;p->from=q;q=p;p=t;}close[srcX][srcY].from=q->from;return&(close[srcX][srcY]);caseNoSolution:returnNULL;}returnNULL;}staticClose*start;staticintshortestep;intprintShortest(){Close*p;intstep=0;p=getShortest();start=p;if(!p){return0;}else{while(p->from){graph[p->cur->x][p->cur->y].value=Pass;printf((%d,%d)→ ,p->cur->x,p->cur->y);p=p->from;step++;}printf((%d,%d) ,p->cur->x,p->cur->y);graph[srcX][srcY].value=Source;graph[dstX][dstY].value=Destination;returnstep;}}voidclearMap(){//ClearMapMarksofStepsClose*p=start;while(p){graph[p->cur->x][p->cur->y].value=Reachable;p=p->from;}graph[srcX][srcY].value=map[srcX][srcY];graph[dstX][dstY].value=map[dstX][dstY];}voidprintDepth(){inti,j;for(i=0;i<Height;i++){for(j=0;j<Width;j++){if(map[i][j]){printf(%s,Symbol[graph[i][j].value]);}else{printf(%2.0lf,close[i][j].G);}}puts();}puts();}voidprintSur(){inti,j;for(i=0;i<Height;i++){for(j=0;j<Width;j++){printf(%02x,graph[i][j].sur);}puts();}puts();}voidprintH(){inti,j;for(i=0;i<Height;i++){for(j=0;j<Width;j++){printf(%02d,close[i][j].H);}puts();}puts();}intmain(intargc,constchar**argv){initGraph(map,0,0,0,0);printMap();while(scanf(%d%d%d%d,&srcX,&srcY,&dstX,&dstY)!=EOF){if(within(srcX,srcY)&&within(dstX,dstY)){if(shortestep=printShortest()){printf(從(%d,%d)到(%d,%d)的最短步數是:%d ,srcX,srcY,dstX,dstY,shortestep);printMap();clearMap();bfs();//printDepth();puts((shortestep==close[dstX][dstY].G)?正確:錯誤);clearMap();}else{printf(從(%d,%d)不可到達(%d,%d) ,srcX,srcY,dstX,dstY);}}else{puts(輸入錯誤!);}}return(0);}

『陸』 A*演算法是怎麼來的,歷史背景是啥,誰提出的A*演算法幫幫忙,謝謝!

1968年,的一篇論文,「P. E. Hart, N. J. Nilsson, and B. Raphael. A formal basis for the heuristic determination of minimum cost paths in graphs. IEEE Trans. Syst. Sci. and Cybernetics, SSC-4(2):100-107, 1968」。從此,一種精巧、高效的演算法------A*演算法橫空出世了,並在相關領域得到了廣泛的應用。

『柒』 A*演算法的好處

其實A*演算法也是一種最好優先的演算法
只不過要加上一些約束條件罷了。由於在一些問題求解時,我們希望能夠求解出狀態空間搜索的最短路徑,也就是用最快的方法求解問題,A*就是干這種事情的!
我們先下個定義,如果一個估價函數可以找出最短的路徑,我們稱之為可採納性。A*演算法是一個可採納的最好優先演算法。A*演算法的估價函數可表示為:
f'(n) = g'(n) + h'(n)
這里,f'(n)是估價函數,g'(n)是起點到節點n的最短路徑值,h'(n)是n到目標的最短路經的啟發值。由於這個f'(n)其實是無法預先知道的,所以我們用前面的估價函數f(n)做近似。g(n)代替g'(n),但 g(n)>=g'(n)才可(大多數情況下都是滿足的,可以不用考慮),h(n)代替h'(n),但h(n)<=h'(n)才可(這一點特別的重要)。可以證明應用這樣的估價函數是可以找到最短路徑的,也就是可採納的。我們說應用這種估價函數的最好優先演算法就是A*演算法。
舉一個例子,其實廣度優先演算法就是A*演算法的特例。其中g(n)是節點所在的層數,h(n)=0,這種h(n)肯定小於h'(n),所以由前述可知廣度優先演算法是一種可採納的。實際也是。當然它是一種最臭的A*演算法。
再說一個問題,就是有關h(n)啟發函數的信息性。h(n)的信息性通俗點說其實就是在估計一個節點的值時的約束條件,如果信息越多或約束條件越多則排除的節點就越多,估價函數越好或說這個演算法越好。這就是為什麼廣度優先演算法的那麼臭的原因了,誰叫它的h(n)=0,一點啟發信息都沒有。但在游戲開發中由於實時性的問題,h(n)的信息越多,它的計算量就越大,耗費的時間就越多。就應該適當的減小h(n)的信息,即減小約束條件。但演算法的准確性就差了,這里就有一個平衡的問題。

『捌』 搜索演算法中,A演算法A*演算法的區別(急)

A演算法一般指某個搜索演算法的樸素的思路
A*指使用了啟發式搜索之後的演算法,也就是運算速度會快很多,但不一定能保證最後得到最優解

『玖』 Apriori演算法是什麼適用於什麼情境

經典的關聯規則挖掘演算法包括Apriori演算法和FP-growth演算法。apriori演算法多次掃描交易資料庫,每次利用候選頻繁集產生頻繁集;而FP-growth則利用樹形結構,無需產生候選頻繁集而是直接得到頻繁集,大大減少掃描交易資料庫的次數,從而提高了演算法的效率。但是apriori的演算法擴展性較好,可以用於並行計算等領域。

Apriori algorithm是關聯規則里一項基本演算法。是由Rakesh Agrawal和Ramakrishnan Srikant兩位博士在1994年提出的關聯規則挖掘演算法。關聯規則的目的就是在一個數據集中找出項與項之間的關系,也被稱為購物藍分析 (Market Basket analysis),因為「購物藍分析」很貼切的表達了適用該演算法情景中的一個子集。

『拾』 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 的函數值。

熱點內容
刪除文件夾時顯示在另一程序打開 發布:2025-01-17 06:03:01 瀏覽:543
安卓手機怎麼裝驅動 發布:2025-01-17 06:02:17 瀏覽:622
安卓微信拍了拍怎麼改 發布:2025-01-17 05:57:31 瀏覽:46
BMF伺服器的系統服務怎麼關 發布:2025-01-17 05:50:29 瀏覽:876
免刷安卓系統怎麼進入usb調試 發布:2025-01-17 05:48:21 瀏覽:837
資料庫的三層架構 發布:2025-01-17 05:17:36 瀏覽:149
雲頂之弈有人開腳本怎麼舉報 發布:2025-01-17 05:16:59 瀏覽:682
sql包含數字 發布:2025-01-17 05:11:56 瀏覽:292
密碼忘記了怎麼查看 發布:2025-01-17 05:02:30 瀏覽:682
腳本執行sql語句 發布:2025-01-17 04:47:51 瀏覽:702