定義
了解了hash基本定義,就不能不提到一些著名的hash算法,MD5 和 SHA1 可以說是目前套用最廣泛的Hash算法,而它們都是以 MD4 為基礎設計的。那么它們都是什麼意思呢?
這裡簡單說一下:
(1) MD4
MD4(RFC 1320)是 MIT 的Ronald L. Rivest在 1990 年設計的,MD 是 Message Digest 的縮寫。它適用在32位字長的處理器上用高速軟體實現--它是基於 32位運算元的位操作來實現的。
(2) MD5
MD5(RFC 1321)是 Rivest 於1991年對MD4的改進版本。它對輸入仍以512位分組,其輸出是4個32位字的級聯,與 MD4 相同。MD5比MD4來得複雜,並且速度較之要慢一點,但更安全,在抗分析和抗差分方面表現更好
(3) SHA1
SHA1是由NIST NSA設計為同DSA一起使用的,它對長度小於2^64位的輸入,產生長度為160bit的散列值,因此抗窮舉(brute-force)性更好。SHA-1 設計時基於和MD4相同原理,並且模仿了該算法。
算法用途
HASH主要用於信息安全領域中加密算法,它把一些不同長度的信息轉化成雜亂的128位的編碼里,叫做HASH值. 也可以說,hash就是找到一種數據內容和數據存放地址之間的映射關係。Hash算法在信息安全方面的套用主要體現在以下的3個方面:
(1) 檔案校驗
我們比較熟悉的校驗算法有奇偶校驗和CRC校驗,這2種校驗並沒有抗數據篡改的能力,它們一定程度上能檢測並糾正數據傳輸中的信道誤碼,但卻不能防止對數據的惡意破壞。
MD5 Hash算法的"數字指紋"特性,使它成為目前套用最廣泛的一種檔案完整性校驗和(Checksum)算法,不少Unix系統有提供計算md5 checksum的命令。
(2)數字簽名
Hash 算法也是現代密碼體系中的一個重要組成部分。由於非對稱算法的運算速度較慢,所以在數字簽名協定中,單向散列函式扮演了一個重要的角色。對 Hash 值,又稱"數字摘要"進行數字簽名,在統計上可以認為與對檔案本身進行數字簽名是等效的。而且這樣的協定還有其他的優點。
(3) 鑒權協定
如下的鑒權協定又被稱作"挑戰--認證模式:在傳輸信道是可被偵聽,但不可被篡改的情況下,這是一種簡單而安全的方法。
hash檔案
我們經常在emule日誌裡面看到,emule正在hash檔案,這裡就是利用了hash算法的檔案校驗性這個功能了,文章前面已經說了一些這些功能,其實這部分是一個非常複雜的過程,在ftp,bt等軟體裡面都是用的這個基本原理,emule裡面是採用檔案分塊傳輸,這樣傳輸的每一塊都要進行對比校驗,如果錯誤則要進行重新下載,這期間這些相關信息寫入met檔案,直到整個任務完成,這個時候part檔案進行重新命名,然後使用move命令,把它傳送到incoming檔案裡面,然後met檔案自動刪除,所以我們有的時候會遇到hash檔案失敗,就是指的是met裡面的信息出了錯誤不能夠和part檔案匹配,另外有的時候開機也要瘋狂hash,有兩種情況一種是你在第一次使用,這個時候要hash提取所有檔案信息,還有一種情況就是上一次你非法關機,那么這個時候就是要進行排錯校驗了。
關於hash的算法研究,一直是信息科學裡面的一個前沿,尤其在網路技術普及的今天,他的重要性越來越突出,其實我們每天在網上進行的信息交流安全驗證,我們在使用的作業系統密鑰原理,裡面都有它的身影,特別對於那些研究信息安全有興趣的朋友,這更是一個打開信息世界的鑰匙,它在hack世界裡面也是一個研究的焦點.
程式實現
// 說明:Hash函式(即散列函式)在程式設計中的套用目標 ------ 把一個對象通過某種轉換機制對應到一個
//size_t類型(即unsigned long)的整型值。
// 而套用Hash函式的領域主要是 hash表(套用非常廣)、密碼等領域。
// 實現說明:
// ⑴、這裡使用了函式對象以及泛型技術,使得對所有類型的對象(關鍵字)都適用。
// ⑵、常用類型有對應的偏特化,比如string、char*、各種整形等。
// ⑶、版本可擴展,如果你對某種類型有特殊的需要,可以在後面實現專門化。
// ⑷、以下實現一般放在頭檔案中,任何包含它的都可使用hash函式對象。
//------------------------------------實現------------------------------------------------
#include <string>
using std::string;
inlinesize_thash_str(const char* s)
{
unsigned long res = 0;
for (; *s; ++s)
res = 5 * res + *s;
returnsize_t(res);
}
template <class Key>
struct hash
{
size_toperator () (const Key& k) const;
};
// 一般的對象,比如:vector< queue<string> >;的對象,需要強制轉化
template < class Key >
size_thash<Key>::operator () (const Key& k) const
{
size_tres = 0;
size_tlen = sizeof(Key);
const char* p = reinterpret_cast<const char*>(&k);
while (len--)
{
res = (res<<1)^*p++;
}
return res;
}
// 偏特化
template<>
size_thash< string >::operator () (const string& str) const
{
return hash_str(str.c_str());
}
typedef char* PChar;
template<>
size_thash<PChar>::operator () (const PChar& s) const
{
return hash_str(s);
}
typedef const char* PCChar;
template<>
size_thash<PCChar>::operator () (const PCChar& s) const
{
return hash_str(s);
}
template<> size_t hash<char>::operator () (const char& x) const { return x; }
template<> size_t hash<unsigned char>::operator () (const unsigned char& x) const { return x; }
template<> size_t hash<signed char>::operator () (const signed char& x) const { return x; }
template<> size_t hash<short>::operator () (const short& x) const { return x; }
template<> size_t hash<unsigned short>::operator () (const unsigned short& x) const { return x; }
template<> size_t hash<int>::operator () (const int& x) const { return x; }
template<> size_t hash<unsigned int>::operator () (const unsigned int& x) const { return x; }
template<> size_t hash<long>::operator () (const long& x) const { return x; }
template<> size_t hash<unsigned long>::operator () (const unsigned long& x) const { return x; }
// 使用說明:
//
// ⑴、使用時首先由於是泛型,所以要加上關鍵字類型。
//
// ⑵、其次要有一個函式對象,可以臨時、局部、全局的,只要在作用域就可以。
//
// ⑶、套用函式對象作用於對應類型的對象。
//----------------------- hash函式使用舉例 -------------------------
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> vstr⑵;
vstr[0] = "sjw";
vstr[1] = "suninf";
hash<string> strhash; // 局部函式對象
cout << " Hash value: " << strhash(vstr[0]) << endl;
cout << " Hash value: " << strhash(vstr[1]) << endl;
cout << " Hash value: " << hash< vector<string> >() (vstr) << endl;
cout << " Hash value: " << hash<int>() (100) << endl; // hash<int>() 臨時函式對象
return 0;
}