標籤:演算法
引用wiki的定義,散列函數(或散列演算法,英語:Hash Function)是一種從任何一種資料中建立小的數字“指紋”的方法。該函數將資料打亂混合,重新建立一個叫做散列值的指紋。散列值通常用來代表一個短的隨機字母和數字組成的字串。好的散列函數在輸入欄位中很少出現散列衝突。在散列表和資料處理中,不抑制衝突來區別資料,會使得資料庫記錄更難找到。(具體專業術語請自行度娘)
MD5是單向散列演算法的一種,全稱是Message-Digest Algorithm 5(資訊-摘要演算法),經MD2、MD3和MD4發展而來。這裡所謂單向,只能向後計算最終值,不能通過反向計算出初始值。
MD5的性質:
輸入任意長度的資訊,經過處理,輸出為128位的資訊(數位指紋)
不同的輸入得到的不同的結果(唯一性)
根據128位的輸出結果不可能反推出輸入的資訊(無法復原)
MD5演算法步驟:
1、補位
首先要進行補位,使得補位後資訊的長度對512求餘為448。即資料擴充至
K*512+448(bit),即K*64+56(byte),K為自然數。具體補位操作:先補一個1,後面補0至滿足上述要求。最少要補1bit,最多補512bit。
2、補長度
在K*64+56(byte)的基礎上補上8byte,這8byte是用來儲存原始資訊的長度。
3、初始化MD緩衝器
用一個四個32位的緩衝器(A,B,C,D)進行MD5值的計算,初始化使用的是十六進位,注意低位元組在前:
word A: 01 23 45 67
word B: 89 ab cd ef
word C: fe dc ba 98
word D: 76 54 32 10
由於記憶體儲存方向和平時書寫是相反的,所以定義的時候應該是:
#define A 0x67452301UL
#define B 0xEFCDAB89UL
#define C 0x98BADCFEUL
#define D 0x10325476UL
4、輔助函數與加密函數
首先定義4個輔助函數:
#define F( X, Y, Z ) ( ( (X) & (Y) ) | ( (~(X)) & (Z) ) )
#define G( X, Y, Z ) ( ( (X) & (Z) ) | ( (Y) & (~(Z)) ) )
#define H( X, Y, Z ) ( (X) ^ (Y) ^ (Z) )
#define I( X, Y, Z ) ( (Y) ^ ( (X) | (~(Z)) ) )
然後定義4個加密函數:
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + ac; \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + ac; \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + ac; \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + ac; \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
具體C++實現演算法下載
加密散列演算法——MD5