導航:首頁 > 程序命令 > 哈希表命令

哈希表命令

發布時間:2022-07-05 05:18:17

1. 誰能幫我解釋一下「哈希表」的詳細含義謝謝了

散列表(Hash table,也叫哈希表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫做散列函數,存放記錄的數組叫做散列表。
[編輯本段]基本概念
* 若結構中存在關鍵字和K相等的記錄,則必定在f(K)的存儲位置上。由此,不需比較便可直接取得所查記錄。稱這個對應關系f為散列函數(Hash function),按這個思想建立的表為散列表。 * 對不同的關鍵字可能得到同一散列地址,即key1≠key2,而f(key1)=f(key2),這種現象稱沖突。具有相同函數值的關鍵字對該散列函數來說稱做同義詞。綜上所述,根據散列函數H(key)和處理沖突的方法將一組關鍵字映象到一個有限的連續的地址集(區間)上,並以關鍵字在地址集中的「象」 作為記錄在表中的存儲位置,這種表便稱為散列表,這一映象過程稱為散列造表或散列,所得的存儲位置稱散列地址。 * 若對於關鍵字集合中的任一個關鍵字,經散列函數映象到地址集合中任何一個地址的概率是相等的,則稱此類散列函數為均勻散列函數(Uniform Hash function),這就是使關鍵字經過散列函數得到一個「隨機的地址」,從而減少沖突。
[編輯本段]常用的構造散列函數的方法
散列函數能使對一個數據序列的訪問過程更加迅速有效,通過散列函數,數據元素將被更快地定位ǐ 1. 直接定址法:取關鍵字或關鍵字的某個線性函數值為散列地址。即H(key)=key或H(key) = a•key + b,其中a和b為常數(這種散列函數叫做自身函數) 2. 數字分析法 3. 平方取中法 4. 折疊法 5. 隨機數法 6. 除留余數法:取關鍵字被某個不大於散列表表長m的數p除後所得的余數為散列地址。即 H(key) = key MOD p, p<=m。不僅可以對關鍵字直接取模,也可在折疊、平方取中等運算之後取模。對p的選擇很重要,一般取素數或m,若p選的不好,容易產生同義詞。
[編輯本段]處理沖突的方法
1. 開放定址法:Hi=(H(key) + di) MOD m, i=1,2,…, k(k<=m-1),其中H(key)為散列函數,m為散列表長,di為增量序列,可有下列三種取法: 1. di=1,2,3,…, m-1,稱線性探測再散列; 2. di=1^2, (-1)^2, 2^2,(-2)^2, (3)^2, …, ±(k)^2,(k<=m/2)稱二次探測再散列; 3. di=偽隨機數序列,稱偽隨機探測再散列。 == 2. 再散列法:Hi=RHi(key), i=1,2,…,k RHi均是不同的散列函數,即在同義詞產生地址沖突時計算另一個散列函數地址,直到沖突不再發生,這種方法不易產生「聚集」,但增加了計算時間。 3. 鏈地址法(拉鏈法) 4. 建立一個公共溢出區
[編輯本段]查找的性能分析
散列表的查找過程基本上和造表過程相同。一些關鍵碼可通過散列函數轉換的地址直接找到,另一些關鍵碼在散列函數得到的地址上產生了沖突,需要按處理沖突的方法進行查找。在介紹的三種處理沖突的方法中,產生沖突後的查找仍然是給定值與關鍵碼進行比較的過程。所以,對散列表查找效率的量度,依然用平均查找長度來衡量。 查找過程中,關鍵碼的比較次數,取決於產生沖突的多少,產生的沖突少,查找效率就高,產生的沖突多,查找效率就低。因此,影響產生沖突多少的因素,也就是影響查找效率的因素。影響產生沖突多少有以下三個因素: 1. 散列函數是否均勻; 2. 處理沖突的方法; 3. 散列表的裝填因子。 散列表的裝填因子定義為:α= 填入表中的元素個數 / 散列表的長度 α是散列表裝滿程度的標志因子。由於表長是定值,α與「填入表中的元素個數」成正比,所以,α越大,填入表中的元素較多,產生沖突的可能性就越大;α越小,填入表中的元素較少,產生沖突的可能性就越小。 實際上,散列表的平均查找長度是裝填因子α的函數,只是不同處理沖突的方法有不同的函數。 了解了hash基本定義,就不能不提到一些著名的hash演算法,MD5 和 SHA-1 可以說是目前應用最廣泛的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) SHA-1 及其他 SHA1是由NIST NSA設計為同DSA一起使用的,它對長度小於264的輸入,產生長度為160bit的散列值,因此抗窮舉(brute-force)性更好。SHA-1 設計時基於和MD4相同原理,並且模仿了該演算法。 那麼這些Hash演算法到底有什麼用呢? Hash演算法在信息安全方面的應用主要體現在以下的3個方面: (1) 文件校驗 我們比較熟悉的校驗演算法有奇偶校驗和CRC校驗,這2種校驗並沒有抗數據篡改的能力,它們一定程度上能檢測並糾正數據傳輸中的信道誤碼,但卻不能防止對數據的惡意破壞。 MD5 Hash演算法的"數字指紋"特性,使它成為目前應用最廣泛的一種文件完整性校驗和(Checksum)演算法,不少Unix系統有提供計算md5 checksum的命令。 (2) 數字簽名 Hash 演算法也是現代密碼體系中的一個重要組成部分。由於非對稱演算法的運算速度較慢,所以在數字簽名協議中,單向散列函數扮演了一個重要的角色。 對 Hash 值,又稱"數字摘要"進行數字簽名,在統計上可以認為與對文件本身進行數字簽名是等效的。而且這樣的協議還有其他的優點。 (3) 鑒權協議 如下的鑒權協議又被稱作挑戰--認證模式:在傳輸信道是可被偵聽,但不可被篡改的情況下,這是一種簡單而安全的方法。 MD5、SHA1的破解 2004年8月17日,在美國加州聖芭芭拉召開的國際密碼大會上,山東大學王小雲教授在國際會議上首次宣布了她及她的研究小組近年來的研究成果——對MD5、HAVAL-128、MD4和RIPEMD等四個著名密碼演算法的破譯結果。 次年二月宣布破解SHA-1密碼。
[編輯本段]實際應用
以上就是一些關於hash以及其相關的一些基本預備知識。那麼在emule裡面他具體起到什麼作用呢? 大家都知道emule是基於P2P (Peer-to-peer的縮寫,指的是點對點的意思的軟體), 它採用了"多源文件傳輸協議」(MFTP,the Multisource FileTransfer Protocol)。在協議中,定義了一系列傳輸、壓縮和打包還有積分的標准,emule 對於每個文件都有md5-hash的演算法設置,這使得該文件獨一無二,並且在整個網路上都可以追蹤得到。 什麼是文件的hash值呢? MD5-Hash-文件的數字文摘通過Hash函數計算得到。不管文件長度如何,它的Hash函數計算結果是一個固定長度的數字。與加密演算法不同,這一個Hash演算法是一個不可逆的單向函數。採用安全性高的Hash演算法,如MD5、SHA時,兩個不同的文件幾乎不可能得到相同的Hash結果。因此,一旦文件被修改,就可檢測出來。 當我們的文件放到emule裡面進行共享發布的時候,emule會根據hash演算法自動生成這個文件的hash值,他就是這個文件唯一的身份標志,它包含了這個文件的基本信息,然後把它提交到所連接的伺服器。當有他人想對這個文件提出下載請求的時候, 這個hash值可以讓他人知道他正在下載的文件是不是就是他所想要的。尤其是在文件的其他屬性被更改之後(如名稱等)這個值就更顯得重要。而且伺服器還提供了,這個文件當前所在的用戶的地址,埠等信息,這樣emule就知道到哪裡去下載了。 一般來講我們要搜索一個文件,emule在得到了這個信息後,會向被添加的伺服器發出請求,要求得到有相同hash值的文件。而伺服器則返回持有這個文件的用戶信息。這樣我們的客戶端就可以直接的和擁有那個文件的用戶溝通,看看是不是可以從他那裡下載所需的文件。 對於emule中文件的hash值是固定的,也是唯一的,它就相當於這個文件的信息摘要,無論這個文件在誰的機器上,他的hash值都是不變的,無論過了多長時間,這個值始終如一,當我們在進行文件的下載上傳過程中,emule都是通過這個值來確定文件。 那麼什麼是userhash呢? 道理同上,當我們在第一次使用emule的時候,emule會自動生成一個值,這個值也是唯一的,它是我們在emule世界裡面的標志,只要你不卸載,不刪除config,你的userhash值也就永遠不變,積分制度就是通過這個值在起作用,emule裡面的積分保存,身份識別,都是使用這個值,而和你的id和你的用戶名無關,你隨便怎麼改這些東西,你的userhash值都是不變的,這也充分保證了公平性。其實他也是一個信息摘要,只不過保存的不是文件信息,而是我們每個人的信息。 那麼什麼是hash文件呢? 我們經常在emule日誌裡面看到,emule正在hash文件,這里就是利用了hash演算法的文件校驗性這個功能了,文章前面已經說了一些這些功能,其實這部分是一個非常復雜的過程,目前在ftp,bt等軟體裡面都是用的這個基本原理,emule裡面是採用文件分塊傳輸,這樣傳輸的每一塊都要進行對比校驗,如果錯誤則要進行重新下載,這期間這些相關信息寫入met文件,直到整個任務完成,這個時候part文件進行重新命名,然後使用move命令,把它傳送到incoming文件裡面,然後met文件自動刪除,所以我們有的時候會遇到hash文件失敗,就是指的是met裡面的信息出了錯誤不能夠和part文件匹配,另外有的時候開機也要瘋狂hash,有兩種情況一種是你在第一次使用,這個時候要hash提取所有文件信息,還有一種情況就是上一次你非法關機,那麼這個時候就是要進行排錯校驗了。 關於hash的演算法研究,一直是信息科學裡面的一個前沿,尤其在網路技術普及的今天,他的重要性越來越突出,其實我們每天在網上進行的信息交流安全驗證,我們在使用的操作系統密鑰原理,裡面都有它的身影,特別對於那些研究信息安全有興趣的朋友,這更是一個打開信息世界的鑰匙,他在hack世界裡面也是一個研究的焦點。 一般的線性表、樹中,記錄在結構中的相對位置是隨機的即和記錄的關鍵字之間不存在確定的關系,在結構中查找記錄時需進行一系列和關鍵字的比較。這一類查找方法建立在「比較」的基礎上,查找的效率與比較次數密切相關。理想的情況是能直接找到需要的記錄,因此必須在記錄的存儲位置和它的關鍵字之間建立一確定的對應關系f,使每個關鍵字和結構中一個唯一的存儲位置相對應。因而查找時,只需根據這個對應關系f找到給定值K的像f(K)。若結構中存在關鍵字和K相等的記錄,則必定在f(K)的存儲位置上,由此不需要進行比較便可直接取得所查記錄。在此,稱這個對應關系f為哈希函數,按這個思想建立的表為哈希表(又稱為雜湊法或散列表)。 哈希表不可避免沖突(collision)現象:對不同的關鍵字可能得到同一哈希地址 即key1≠key2,而hash(key1)=hash(key2)。具有相同函數值的關鍵字對該哈希函數來說稱為同義詞(synonym)。 因此,在建造哈希表時不僅要設定一個好的哈希函數,而且要設定一種處理沖突的方法。可如下描述哈希表:根據設定的哈希函數H(key)和所選中的處理沖突的方法,將一組關鍵字映象到一個有限的、地址連續的地址集(區間)上並以關鍵字在地址集中的「象」作為相應記錄在表中的存儲位置,這種表被稱為哈希表。 對於動態查找表而言,1) 表長不確定;2)在設計查找表時,只知道關鍵字所屬范圍,而不知道確切的關鍵字。因此,一般情況需建立一個函數關系,以f(key)作為關鍵字為key的錄在表中的位置,通常稱這個函數f(key)為哈希函數。(注意:這個函數並不一定是數學函數) 哈希函數是一個映象,即:將關鍵字的集合映射到某個地址集合上,它的設置很靈活,只要這個地址集合的大小不超出允許范圍即可。 現實中哈希函數是需要構造的,並且構造的好才能使用的好。 用途:加密,解決沖突問題。。。。 用途很廣,比特精靈中就使用了哈希函數,你可 以自己看看。 具體可以學習一下數據結構和演算法的書。
[編輯本段]字元串哈希函數
(著名的ELFhash演算法) int ELFhash(char *key) { unsigned long h=0; while(*key) { h=(h<<4)+*key++; unsigned long g=h&0Xf0000000L; if(g) h^=g>>24; h&=~g; } return h%MOD; }

2. 哈希表的查找性能

散列表的查找過程基本上和造表過程相同。一些關鍵碼可通過散列函數轉換的地址直接找到,另一些關鍵碼在散列函數得到的地址上產生了沖突,需要按處理沖突的方法進行查找。在介紹的三種處理沖突的方法中,產生沖突後的查找仍然是給定值與關鍵碼進行比較的過程。所以,對散列表查找效率的量度,依然用平均查找長度來衡量。
查找過程中,關鍵碼的比較次數,取決於產生沖突的多少,產生的沖突少,查找效率就高,產生的沖突多,查找效率就低。因此,影響產生沖突多少的因素,也就是影響查找效率的因素。影響產生沖突多少有以下三個因素:
1. 散列函數是否均勻;
2. 處理沖突的方法;
3. 散列表的裝填因子。
散列表的裝填因子定義為:α= 填入表中的元素個數 / 散列表的長度
α是散列表裝滿程度的標志因子。由於表長是定值,α與「填入表中的元素個數」成正比,所以,α越大,填入表中的元素較多,產生沖突的可能性就越大;α越小,填入表中的元素較少,產生沖突的可能性就越小。
實際上,散列表的平均查找長度是裝填因子α的函數,只是不同處理沖突的方法有不同的函數。
了解了hash基本定義,就不能不提到一些著名的hash演算法,MD5 和 SHA-1 可以說是目前應用最廣泛的Hash演算法,而它們都是以 MD4 為基礎設計的。那麼他們都是什麼意思呢?
這里簡單說一下:
⑴ MD4
MD4(RFC 1320)是 MIT 的 Ronald L. Rivest 在 1990 年設計的,MD 是 Message Digest 的縮寫。它適用在32位字長的處理器上用高速軟體實現--它是基於 32 位操作數的位操作來實現的。
⑵ MD5
MD5(RFC 1321)是 Rivest 於1991年對MD4的改進版本。它對輸入仍以512位分組,其輸出是4個32位字的級聯,與 MD4 相同。MD5比MD4來得復雜,並且速度較之要慢一點,但更安全,在抗分析和抗差分方面表現更好
⑶ SHA-1 及其他
SHA1是由NIST NSA設計為同DSA一起使用的,它對長度小於264的輸入,產生長度為160bit的散列值,因此抗窮舉(brute-force)性更好。SHA-1 設計時基於和MD4相同原理,並且模仿了該演算法。
那麼這些Hash演算法到底有什麼用呢?
Hash演算法在信息安全方面的應用主要體現在以下的3個方面:
⑴ 文件校驗
我們比較熟悉的校驗演算法有奇偶校驗和CRC校驗,這2種校驗並沒有抗數據篡改的能力,它們一定程度上能檢測出數據傳輸中的信道誤碼,但卻不能防止對數據的惡意破壞。
MD5 Hash演算法的數字指紋特性,使它成為目前應用最廣泛的一種文件完整性校驗和(Checksum)演算法,不少Unix系統有提供計算md5 checksum的命令。
⑵ 數字簽名
Hash 演算法也是現代密碼體系中的一個重要組成部分。由於非對稱演算法的運算速度較慢,所以在數字簽名協議中,單向散列函數扮演了一個重要的角色。對 Hash 值,又稱數字摘要進行數字簽名,在統計上可以認為與對文件本身進行數字簽名是等效的。而且這樣的協議還有其他的優點。
⑶ 鑒權協議
如下的鑒權協議又被稱作挑戰--認證模式:在傳輸信道是可被偵聽,但不可被篡改的情況下,這是一種簡單而安全的方法。
MD5、SHA1的破解
2004年8月17日,在美國加州聖芭芭拉召開的國際密碼大會上,山東大學王小雲教授在國際會議上首次宣布了她及她的研究小組的研究成果——對MD5、HAVAL-128、MD4和RIPEMD等四個著名密碼演算法的破譯結果。2005年2月宣布破解SHA-1密碼。

3. 哈希表在計算機中有什麼用,急用!先謝謝啊!

哈希表

基本概念
* 若結構中存在關鍵字和K相等的記錄,則必定在f(K)的存儲位置上。由此,不需比較便可直接取得所查記錄。稱這個對應關系f為散列函數(Hash function),按這個思想建立的表為散列表。 * 對不同的關鍵字可能得到同一散列地址,即key1≠key2,而f(key1)=f(key2),這種現象稱沖突。具有相同函數值的關鍵字對該散列函數來說稱做同義詞。綜上所述,根據散列函數H(key)和處理沖突的方法將一組關鍵字映象到一個有限的連續的地址集(區間)上,並以關鍵字在地址集中的「象」 作為記錄在表中的存儲位置,這種表便稱為散列表,這一映象過程稱為散列造表或散列,所得的存儲位置稱散列地址。 * 若對於關鍵字集合中的任一個關鍵字,經散列函數映象到地址集合中任何一個地址的概率是相等的,則稱此類散列函數為均勻散列函數(Uniform Hash function),這就是使關鍵字經過散列函數得到一個「隨機的地址」,從而減少沖突。
常用的構造散列函數的方法
散列函數能使對一個數據序列的訪問過程更加迅速有效,通過散列函數,數據元素將被更快地定位ǐ 1. 直接定址法:取關鍵字或關鍵字的某個線性函數值為散列地址。即H(key)=key或H(key) = a•key + b,其中a和b為常數(這種散列函數叫做自身函數) 2. 數字分析法 3. 平方取中法 4. 折疊法 5. 隨機數法 6. 除留余數法:取關鍵字被某個不大於散列表表長m的數p除後所得的余數為散列地址。即 H(key) = key MOD p, p<=m。不僅可以對關鍵字直接取模,也可在折疊、平方取中等運算之後取模。對p的選擇很重要,一般取素數或m,若p選的不好,容易產生同義詞。
處理沖突的方法
1. 開放定址法:Hi=(H(key) + di) MOD m, i=1,2,…, k(k<=m-1),其中H(key)為散列函數,m為散列表長,di為增量序列,可有下列三種取法: 1. di=1,2,3,…, m-1,稱線性探測再散列; 2. di=1^2, (-1)^2, 2^2,(-2)^2, (3)^2, …, ±(k)^2,(k<=m/2)稱二次探測再散列; 3. di=偽隨機數序列,稱偽隨機探測再散列。 == 2. 再散列法:Hi=RHi(key), i=1,2,…,k RHi均是不同的散列函數,即在同義詞產生地址沖突時計算另一個散列函數地址,直到沖突不再發生,這種方法不易產生「聚集」,但增加了計算時間。 3. 鏈地址法(拉鏈法) 4. 建立一個公共溢出區
查找的性能分析
散列表的查找過程基本上和造表過程相同。一些關鍵碼可通過散列函數轉換的地址直接找到,另一些關鍵碼在散列函數得到的地址上產生了沖突,需要按處理沖突的方法進行查找。在介紹的三種處理沖突的方法中,產生沖突後的查找仍然是給定值與關鍵碼進行比較的過程。所以,對散列表查找效率的量度,依然用平均查找長度來衡量。 查找過程中,關鍵碼的比較次數,取決於產生沖突的多少,產生的沖突少,查找效率就高,產生的沖突多,查找效率就低。因此,影響產生沖突多少的因素,也就是影響查找效率的因素。影響產生沖突多少有以下三個因素: 1. 散列函數是否均勻; 2. 處理沖突的方法; 3. 散列表的裝填因子。 散列表的裝填因子定義為:α= 填入表中的元素個數 / 散列表的長度 α是散列表裝滿程度的標志因子。由於表長是定值,α與「填入表中的元素個數」成正比,所以,α越大,填入表中的元素較多,產生沖突的可能性就越大;α越小,填入表中的元素較少,產生沖突的可能性就越小。 實際上,散列表的平均查找長度是裝填因子α的函數,只是不同處理沖突的方法有不同的函數。 了解了hash基本定義,就不能不提到一些著名的hash演算法,MD5 和 SHA-1 可以說是目前應用最廣泛的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) SHA-1 及其他 SHA1是由NIST NSA設計為同DSA一起使用的,它對長度小於264的輸入,產生長度為160bit的散列值,因此抗窮舉(brute-force)性更好。SHA-1 設計時基於和MD4相同原理,並且模仿了該演算法。 那麼這些Hash演算法到底有什麼用呢? Hash演算法在信息安全方面的應用主要體現在以下的3個方面: (1) 文件校驗 我們比較熟悉的校驗演算法有奇偶校驗和CRC校驗,這2種校驗並沒有抗數據篡改的能力,它們一定程度上能檢測並糾正數據傳輸中的信道誤碼,但卻不能防止對數據的惡意破壞。 MD5 Hash演算法的"數字指紋"特性,使它成為目前應用最廣泛的一種文件完整性校驗和(Checksum)演算法,不少Unix系統有提供計算md5 checksum的命令。 (2) 數字簽名 Hash 演算法也是現代密碼體系中的一個重要組成部分。由於非對稱演算法的運算速度較慢,所以在數字簽名協議中,單向散列函數扮演了一個重要的角色。 對 Hash 值,又稱"數字摘要"進行數字簽名,在統計上可以認為與對文件本身進行數字簽名是等效的。而且這樣的協議還有其他的優點。 (3) 鑒權協議 如下的鑒權協議又被稱作挑戰--認證模式:在傳輸信道是可被偵聽,但不可被篡改的情況下,這是一種簡單而安全的方法。 MD5、SHA1的破解 2004年8月17日,在美國加州聖芭芭拉召開的國際密碼大會上,山東大學王小雲教授在國際會議上首次宣布了她及她的研究小組近年來的研究成果——對MD5、HAVAL-128、MD4和RIPEMD等四個著名密碼演算法的破譯結果。 次年二月宣布破解SHA-1密碼。
實際應用
以上就是一些關於hash以及其相關的一些基本預備知識。那麼在emule裡面他具體起到什麼作用呢? 大家都知道emule是基於P2P (Peer-to-peer的縮寫,指的是點對點的意思的軟體), 它採用了"多源文件傳輸協議」(MFTP,the Multisource FileTransfer Protocol)。在協議中,定義了一系列傳輸、壓縮和打包還有積分的標准,emule 對於每個文件都有md5-hash的演算法設置,這使得該文件獨一無二,並且在整個網路上都可以追蹤得到。 什麼是文件的hash值呢? MD5-Hash-文件的數字文摘通過Hash函數計算得到。不管文件長度如何,它的Hash函數計算結果是一個固定長度的數字。與加密演算法不同,這一個Hash演算法是一個不可逆的單向函數。採用安全性高的Hash演算法,如MD5、SHA時,兩個不同的文件幾乎不可能得到相同的Hash結果。因此,一旦文件被修改,就可檢測出來。 當我們的文件放到emule裡面進行共享發布的時候,emule會根據hash演算法自動生成這個文件的hash值,他就是這個文件唯一的身份標志,它包含了這個文件的基本信息,然後把它提交到所連接的伺服器。當有他人想對這個文件提出下載請求的時候, 這個hash值可以讓他人知道他正在下載的文件是不是就是他所想要的。尤其是在文件的其他屬性被更改之後(如名稱等)這個值就更顯得重要。而且伺服器還提供了,這個文件當前所在的用戶的地址,埠等信息,這樣emule就知道到哪裡去下載了。 一般來講我們要搜索一個文件,emule在得到了這個信息後,會向被添加的伺服器發出請求,要求得到有相同hash值的文件。而伺服器則返回持有這個文件的用戶信息。這樣我們的客戶端就可以直接的和擁有那個文件的用戶溝通,看看是不是可以從他那裡下載所需的文件。 對於emule中文件的hash值是固定的,也是唯一的,它就相當於這個文件的信息摘要,無論這個文件在誰的機器上,他的hash值都是不變的,無論過了多長時間,這個值始終如一,當我們在進行文件的下載上傳過程中,emule都是通過這個值來確定文件。 那麼什麼是userhash呢? 道理同上,當我們在第一次使用emule的時候,emule會自動生成一個值,這個值也是唯一的,它是我們在emule世界裡面的標志,只要你不卸載,不刪除config,你的userhash值也就永遠不變,積分制度就是通過這個值在起作用,emule裡面的積分保存,身份識別,都是使用這個值,而和你的id和你的用戶名無關,你隨便怎麼改這些東西,你的userhash值都是不變的,這也充分保證了公平性。其實他也是一個信息摘要,只不過保存的不是文件信息,而是我們每個人的信息。 那麼什麼是hash文件呢? 我們經常在emule日誌裡面看到,emule正在hash文件,這里就是利用了hash演算法的文件校驗性這個功能了,文章前面已經說了一些這些功能,其實這部分是一個非常復雜的過程,目前在ftp,bt等軟體裡面都是用的這個基本原理,emule裡面是採用文件分塊傳輸,這樣傳輸的每一塊都要進行對比校驗,如果錯誤則要進行重新下載,這期間這些相關信息寫入met文件,直到整個任務完成,這個時候part文件進行重新命名,然後使用move命令,把它傳送到incoming文件裡面,然後met文件自動刪除,所以我們有的時候會遇到hash文件失敗,就是指的是met裡面的信息出了錯誤不能夠和part文件匹配,另外有的時候開機也要瘋狂hash,有兩種情況一種是你在第一次使用,這個時候要hash提取所有文件信息,還有一種情況就是上一次你非法關機,那麼這個時候就是要進行排錯校驗了。 關於hash的演算法研究,一直是信息科學裡面的一個前沿,尤其在網路技術普及的今天,他的重要性越來越突出,其實我們每天在網上進行的信息交流安全驗證,我們在使用的操作系統密鑰原理,裡面都有它的身影,特別對於那些研究信息安全有興趣的朋友,這更是一個打開信息世界的鑰匙,他在hack世界裡面也是一個研究的焦點。 一般的線性表、樹中,記錄在結構中的相對位置是隨機的即和記錄的關鍵字之間不存在確定的關系,在結構中查找記錄時需進行一系列和關鍵字的比較。這一類查找方法建立在「比較」的基礎上,查找的效率與比較次數密切相關。理想的情況是能直接找到需要的記錄,因此必須在記錄的存儲位置和它的關鍵字之間建立一確定的對應關系f,使每個關鍵字和結構中一個唯一的存儲位置相對應。因而查找時,只需根據這個對應關系f找到給定值K的像f(K)。若結構中存在關鍵字和K相等的記錄,則必定在f(K)的存儲位置上,由此不需要進行比較便可直接取得所查記錄。在此,稱這個對應關系f為哈希函數,按這個思想建立的表為哈希表(又稱為雜湊法或散列表)。 哈希表不可避免沖突(collision)現象:對不同的關鍵字可能得到同一哈希地址 即key1≠key2,而hash(key1)=hash(key2)。具有相同函數值的關鍵字對該哈希函數來說稱為同義詞(synonym)。 因此,在建造哈希表時不僅要設定一個好的哈希函數,而且要設定一種處理沖突的方法。可如下描述哈希表:根據設定的哈希函數H(key)和所選中的處理沖突的方法,將一組關鍵字映象到一個有限的、地址連續的地址集(區間)上並以關鍵字在地址集中的「象」作為相應記錄在表中的存儲位置,這種表被稱為哈希表。 對於動態查找表而言,1) 表長不確定;2)在設計查找表時,只知道關鍵字所屬范圍,而不知道確切的關鍵字。因此,一般情況需建立一個函數關系,以f(key)作為關鍵字為key的錄在表中的位置,通常稱這個函數f(key)為哈希函數。(注意:這個函數並不一定是數學函數) 哈希函數是一個映象,即:將關鍵字的集合映射到某個地址集合上,它的設置很靈活,只要這個地址集合的大小不超出允許范圍即可。 現實中哈希函數是需要構造的,並且構造的好才能使用的好。 用途:加密,解決沖突問題。。。。 用途很廣,比特精靈中就使用了哈希函數,你可 以自己看看。 具體可以學習一下數據結構和演算法的書。
字元串哈希函數
(著名的ELFhash演算法) int ELFhash(char *key) { unsigned long h=0; while(*key) { h=(h<<4)+*key++; unsigned long g=h&0Xf0000000L; if(g) h^=g>>24; h&=~g; } return h%MOD; }

4. 哈希表查找的相關概念

HASH全稱是「Hash House Harriers」(簡稱「Hash"、「HHH」,或「 3H」 ),是一項世界性的休閑活動,起源於1938年馬來西亞的吉隆坡,如今在全世界184個國家幾千個城市中都有開展,包括中國的北京、廣州、上海、深圳、烏魯木齊等城市。

Hash活動沒有固定的成員和組織,也不存在固定的模式,各個城市的具體做法各有不同,但所有的hash都有兩個共同的主題:跑步和啤酒,其參加者也因此自稱「The running club with a drinking problem」。經過幾十年的發展,hash活動已經超越簡單的體育鍛煉活動,而形成了一種特色鮮明、獨具魅力的文化。

一、Hash活動崇尚一種自然健康、團結友愛、積極向上、挑戰自我的精神。

Hash中最重要的一件事就是跑步,而且是有趣味、有難度的跑步。每次活動都有一兩名參加者志願充當「兔子」(hare)的角色,事先在野外設置好錯綜復雜的路線,而自稱為獵狗(harriers)的參加者則追蹤而至,頂著烈日驕陽或淋著瓢潑大雨,尋找兔子留下的蛛絲馬跡。不論是攀山越嶺還是涉水過河,是披荊斬棘還是踏污踩糞,只要是兔子布下的路線,獵狗們就義無反顧地一跑到底,決不偷工減料。這樣一兩個小時跑下來,不僅鍛煉了身體,更磨煉了意志。獵狗們在追蹤過程中,每到一個岔路口,都需要分工協作,分頭找路,才能最快地找到正確的道路。而遇上溝溝坎坎或荊棘刺叢的時候,參加者更是會伸出手來互相幫助。如果有人迷了路,他不僅會經歷一次對自己應變能力的挑戰,更將體會到同伴在尋找他的過程中表現出來的團結和友愛。

二、Hash活動體現了一種幽默、開朗、豁達而且自然隨意的生活態度。

在鋼筋混凝土叢林中忙碌的現代人最需要的就是貼近自然,放鬆緊張的身心,而這也正是參加hash的人們所推崇的生活方式。

幽默可是說是全世界hash參加者的共性。他們最擅長的就是自嘲——自稱為「獵狗」,海口的hash參加者還自稱為「害蟲」,每個人有一個可笑甚至惡心的外號,比如「賣女孩的小火柴」、「肉肉」、「骯臟的魚」等等。唱歌、講故事、說笑話、相互捉弄、插科打諢……每一次hash活動都充滿歡笑和快樂。

看看沾滿泥水的跑鞋和掛滿草刺的小腿,暢飲一口冰啤酒高歌一曲,不由得豪氣頓生,早不見了辦公室里拘謹刻板的模樣。新老朋友一起在空曠的野外大聲喊叫,放肆地說笑話逗樂子,縱情地歌唱和歡笑,在音樂聲中又鬧又跳,疲倦的是軀體,而心靈得到了徹底的放鬆。

Hash活動過程中不準從事商業活動,不準打手機,不準談工作,所有參加者都以綽號互稱,遠離銅臭氣和復雜的人事關系,為純真的友誼提供了生長的環境。難怪Hash裡面許多人成了意氣相投的好朋友之後,才猛然發現原來自己連對方是做什麼生意的、有沒有結婚都不知道。

Hash活動不以營利為目的,每次活動的結余歸入基金供大活動時支出;所有工作都由參加者齊心協力地完成;每期的兔子可以按自己的意願自由地組織一次跑步。這正是hash的魅力所在:為參加者提供一個可以盡情展現真我的機會。

正是出於對大自然的熱愛,Hash參加者們對環境保護尤為重視。空瓶空罐絕對不允許亂扔、垃圾袋必須是可降解塑料做的、不準拈花惹草、不得踩壞莊稼、等等,這些規矩都是每一位hash參加者嚴格恪守,並在生活中也身體力行的。海口hash的參加者還曾組織過在五指山頂、牙龍灣、尖峰嶺等風景點清理垃圾的活動。

三、Hash還是一項各種文化匯集、交流的活動。

Hash活動不僅僅是體育休閑活動。Hash參加者強烈的表現欲在這一寬松的環境中得到鼓勵和張揚。他們創造了種種個性鮮明的hash徽標,改編了上千首hash歌曲,製作了不計其數的、風格各異的T恤、帽子、杯墊,出版了大量或精美或簡陋然而同樣精彩的hash雜志、報紙、宣傳冊,在Internet上,只要輸入「hash」或者「hhh」進行搜索,可以發現成百上千個hash網站。可以說,hash已經有了自己的文化。參加過hash活動後,有人可能會不喜歡這種文化,可是沒有人會忘記這樣一種文化。它自有它獨特的、令人無法忘懷的風味。

在衍生出自己的文化之外,Hash活動從一開始就體現了不同文化的碰撞和交流。第一次hash跑步,就是由旅居馬來西亞的英國人組織的。世界各地的hash,吸引了各種各樣不同文化的人參加,尤其是旅居當地的外國人。這一點在英美之外的國家的hash中特別明顯。因此,hash除了帶有明顯的英美文化氣息外,還成了各種文化交匯融合的活動。像在中國的大多數hash,就成了各種外國人和中國人共同喜愛的活動,英語成為主要的交流手段,而他們的徽標、T恤設計中卻透著濃郁的中國文化氣息。Hash還是一個全球性的休閑活動,除了各地自有的hash活動,還有定期舉行的「泛亞hash」、「泛太平洋hash」等等區域性的活動,每四年還有一次「全球hash」。這種大規模的hash,更是雲集來自世界各地的愛好者,無形中也就是一次文化的盛會。Hash活動於生俱來的寬容和自由的特性,為各種不同文化背景的參加者提供了一個平等、寬松、隨意、自由發揮的環境。所有的參加者自由地來,自由地去,各人對各人的言行和安全負責,不論國籍、年齡、種族、膚色、職業、教育程度如何,都只是「獵狗」或者「兔子」這兩種角色之一種,以綽號相稱,甚至真名都不為人知。在「跑步」和「啤酒」這兩個主題下,參加者們徹底放下面子和成見,打破各種人為的隔閡和壁壘,真正玩到一塊兒,發展友誼,取長補短,盡情展現各自的風采。

海口的hash最早也是由外國人發起,除了旅居海口的外國人,還吸引了許多外企的白領和英語愛好者參加。後來由於愛好hash的外國人逐漸離開海口,現在參加海口hash的主要是中國人,其中大部分是旅居海口的內地人。Hash本身的淵源、活動形式及其精神都帶有濃厚的西方文化色彩,必然會對其參與者造成一定的影響,而中國古老的文化也給海口hash烙上獨特的印跡。

海口hash的參與者有老有少、有男有女,分別來自社會各個層面,有著不同的文化素養和人生觀。他們來參加hash,不僅面對hash本身具有的西方文化的沖擊,而且也面臨著相互間不同觀念帶來的沖突。但只要是熱愛運動和自然的人,在接受hash的同時,也就會接受hash寬容、自由的氛圍及其多姿多彩的文化,自然也就會變得更寬容、更善於理解他人。

正是由於hash具有這樣獨特的文化魅力,這項休閑活動才持續了近70年而不衰,風靡全球幾千個城市,受到各界的廣泛關注。尤其是定期舉行的跨地區的hash,比如環亞太地區的hash,或者環東南亞的hash,每次都在不同的城市舉行,對於舉辦城市來說,這無疑是當地旅遊業發展的一次良好契機。

新聞

四川新聞網-成都商報訊 「兔子快跑,不要回頭看,5隻獵狗就在你身後,就要追上來了。」昨日下午,以玉林北路為中心,東南西北四個方向的大街上,突然出現了20多個在炎炎烈日下,流著大汗不停奔跑的年輕人。他們是「成都在線」的年輕網友們,他們將整個城市當成了他們的「游樂場」,玩起了風靡全球的健康休閑游戲——「城市獵狗行動」。看來,這種客居異鄉的外國人的傳統聚會方式已漸漸變成成都白領熱愛的休閑活動。

名詞解釋
城市獵狗行動全稱為Hash House Harriers,是一項世界性的休閑健身活動,代表的是一種健康、真實、自然而又稍帶一點另類氣息的生活態度。在全世界的幾千個城市中都有開展。HASH活動並沒有固定的模式,各個城市的做法各有不同,也不存在固定的HASH成員和組織,但跑步和啤酒是所有HASH中不可缺少的。
HASH規則源於傳統的英國式的紙片追蹤游戲。現在,HASH已經遍及全世界,許多人甚至以到世界各地參加HASH、收集不同的HASH T恤為樂。第一次比賽時,輸的一方必須坐冰。

行動規則
兔子先跑,
獵狗按箭頭追

昨日下午2時許,陸續有網友出現在玉林北路的凹凸酒吧里。「我是兔子,網名『笑死人了』報到」,「我是獵狗,網名『大乖』,我分在哪一組哦?」面對這群嘰嘰喳喳的年輕人,工作人員「冰心洋娃娃」等吼到聲音發啞才將他們一一安排到位:兔子8人,穿上統一的紅色T恤,分東南西北四個方向跑,每個方向兩人,一男一女。獵狗19人,按方向分著白、藍、綠、黑色T恤。

扮兔子的人手一冊地圖,他們將按照地圖上的路線逃跑。兔子出發15分鍾後,獵狗開始行動,他們事先不知道兔子的奔跑路線,只能根據兔子在每個轉彎處留下的箭頭進行尋找。在兔子跑回酒吧前,如果獵狗抓到一隻兔子,獵狗就贏了,反之,就算兔子贏。

捕獵開始
跑暈了,
兔子被獵狗
堵在門口吃掉

「預備,跑!」下午3時10分,8隻兔子踏上了逃命之旅,為防作弊,他們的手機全被隨隊人員繳獲。東線,經一環路、科華路、人民南路等處回到起點;南線,經神仙樹北路、倪家橋等處;西線,經芳草街、肖家河沿街、永豐立交橋、玉林南路等;北線,經一環路、洗面橋街、電信路、人民南路等。

滿懷信心,北線兔子—「麥子」和「阿拉蕾」用了十多秒就跑到了第一個路口,他們在地上貼上了第一個轉彎標志——一個寬約15厘米,長約30厘米的不幹膠箭頭。太陽當空照,又跑了100多米,「阿拉蕾」再也跑不動了,「麥子」只好忍痛拋下她繼續逃命。跑到電信路時,「麥子」已經累得無法邁步了,不時向後張望,生怕獵狗追上來了。「你們在比賽喲,加油,小夥子!」路邊一位大爺見狀忙給他打氣。在大爺的鼓勵下,「麥子」又來了精神。3時50分左右,「麥子」第一個成功逃脫追捕,回到酒吧。

而其他各線情況就有些不妙了——西線兔子貼錯了路標,東線獵狗「大乖」稀里糊塗抄了近路。南線兔子「天才狼」更絕,由於路線錯得太離譜,他比所有人晚到了近半個小時,不幸成為獵狗們在酒吧門口用守株待兔的方法抓到的惟一一隻兔子。

懲罰方式
坐在冰堆上,將一瓶啤酒喝光

盡管獵狗們對比賽規則持諸多保留意見,比如等待15分鍾太長,兔子們留在路上的箭頭容易被路人或風帶走等,但經大家友好協商,組織者「成都在線」管理員「蛇蠍子」仍判定東線和北線兔子贏,南線和貼錯了路標的西線兔子輸。迎接輸家的將是全球通行的懲罰方式——在刺骨的冰塊堆上坐著喝完一瓶啤酒。

在尖叫聲中,上千塊冰塊分兩層鋪到了一張椅子上。「天才狼」被罰第一個坐冰塊。但屁股剛挨到椅子,「天才狼」就被冷得彈了起來,在掌聲和笑聲中,兩名網友上前按住他的肩,他只好強忍寒冷,大喊著「涼快」,喝完了啤酒。除了西線兔子「笑死人了」辯解成功外,剩下的輸家都一一坐上了冰椅。

組織者說
耍的就是一個「鮮」

「成都在線」網站管理員「蛇蠍子」告訴記者,幾個月前他偶然在網上看到了風靡全球的「城市獵狗行動」——HASH,於是,兩個星期前,他們開始籌劃成都網友自己的HASH,並製作了衣服和路標。「成都在線」的網友們大多是年輕人,不喜歡打麻將鬥地主,追求的是一種屬於城市年輕人的獨特耍法,要的就是積極健康,新鮮刺激。「我們大多數人都不知道彼此的真實姓名和職業,這讓我們可以拋開各自現實生活中的身份和地位,在運動和體驗中獲得一種單純的快樂,這就是我們所要的耍法」。

據悉,「成都在線」的網友們常常在網上發起各種新鮮的玩耍方式,比如「城市邊緣角色體驗」、「車聊」等,哪個網友想參加活動,留下自己的網名和聯系方式即可。

網友自白
坐煩了,
何不出來遛遛?

參加昨日「城市獵狗行動」的網友,大多是年齡在25歲左右的年輕人,不少是金融業、策劃行業、設計行業的白領人士。平時,他們大多呆在寫字樓里,缺乏運動,昨日,他們獲得了一次難得的放鬆。

「麥子」(平面設計師)——
盡管我是第一個到達終點的「兔子」,但平時,我成天呆在辦公室里,很少有機會活動筋骨。唉,工作忙啊。所以一看到網友們在組織這個活動,我高興壞了,馬上就報名當一隻「兔子」。盡管被5隻「獵狗」追,但我很有信心。不過這一趟跑下來,我簡直累得上氣不接下氣,看來,得加強鍛煉了。

「大乖」(電子科大大四學生)——
我是被大家公認為跑得最快的「獵狗」,只差10秒鍾就抓到「兔子」了。其實他們哪裡曉得,我是因為不識路才抄了近路,正所謂「塞翁失馬焉知非福」呵。
我馬上就快畢業了,將和他們一樣,坐進寫字樓,以電梯代步,運動的機會越來越少了。所以,這次行動我豈能錯過!

基本知識

Hash,一般翻譯做「散列」,也有直接音譯為」哈希「的,就是把任意長度的輸入(又叫做預映射, pre-image),通過散列演算法,變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間通常遠小於輸入的空間,不同的輸入可能會散列成相同的輸出,而不可能從散列值來唯一的確定輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。

HASH主要用於信息安全領域中加密演算法,他把一些不同長度的信息轉化成雜亂的128位的編碼里,叫做HASH值. 也可以說,hash就是找到一種數據內容和數據存放地址之間的映射關系

了解了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一起使用的,它對長度小於264的輸入,產生長度為160bit的散列值,因此抗窮舉(brute-force)性更好。SHA-1 設計時基於和MD4相同原理,並且模仿了該演算法。

那麼這些Hash演算法到底有什麼用呢?

Hash演算法在信息安全方面的應用主要體現在以下的3個方面:

(1) 文件校驗

我們比較熟悉的校驗演算法有奇偶校驗和CRC校驗,這2種校驗並沒有抗數據篡改的能力,它們一定程度上能檢測並糾正數據傳輸中的信道誤碼,但卻不能防止對數據的惡意破壞。

MD5 Hash演算法的"數字指紋"特性,使它成為目前應用最廣泛的一種文件完整性校驗和(Checksum)演算法,不少Unix系統有提供計算md5 checksum的命令。

(2) 數字簽名

Hash 演算法也是現代密碼體系中的一個重要組成部分。由於非對稱演算法的運算速度較慢,所以在數字簽名協議中,單向散列函數扮演了一個重要的角色。 對 Hash 值,又稱"數字摘要"進行數字簽名,在統計上可以認為與對文件本身進行數字簽名是等效的。而且這樣的協議還有其他的優點。

(3) 鑒權協議

如下的鑒權協議又被稱作挑戰--認證模式:在傳輸信道是可被偵聽,但不可被篡改的情況下,這是一種簡單而安全的方法。以上就是一些關於hash以及其相關的一些基本預備知識。那麼在emule裡面他具體起到什麼作用呢?

什麼是文件的hash值呢?

大家都知道emule是基於P2P (Peer-to-peer的縮寫,指的是點對點的意思的軟體), 它採用了"多源文件傳輸協議」(MFTP,the Multisource FileTransfer Protocol)。在協議中,定義了一系列傳輸、壓縮和打包還有積分的標准,emule 對於每個文件都有md5-hash的演算法設置,這使得該文件獨一無二,並且在整個網路上都可以追蹤得到。

MD5-Hash-文件的數字文摘通過Hash函數計算得到。不管文件長度如何,它的Hash函數計算結果是一個固定長度的數字。與加密演算法不同,這一個Hash演算法是一個不可逆的單向函數。採用安全性高的Hash演算法,如MD5、SHA時,兩個不同的文件幾乎不可能得到相同的Hash結果。因此,一旦文件被修改,就可檢測出來。

當我們的文件放到emule裡面進行共享發布的時候,emule會根據hash演算法自動生成這個文件的hash值,他就是這個文件唯一的身份標志,它包含了這個文件的基本信息,然後把它提交到所連接的伺服器。當有他人想對這個文件提出下載請求的時候, 這個hash值可以讓他人知道他正在下載的文件是不是就是他所想要的。尤其是在文件的其他屬性被更改之後(如名稱等)這個值就更顯得重要。而且伺服器還提供了,這個文件當前所在的用戶的地址,埠等信息,這樣emule就知道到哪裡去下載了。

一般來講我們要搜索一個文件,emule在得到了這個信息後,會向被添加的伺服器發出請求,要求得到有相同hash值的文件。而伺服器則返回持有這個文件的用戶信息。這樣我們的客戶端就可以直接的和擁有那個文件的用戶溝通,看看是不是可以從他那裡下載所需的文件。

對於emule中文件的hash值是固定的,也是唯一的,它就相當於這個文件的信息摘要,無論這個文件在誰的機器上,他的hash值都是不變的,無論過了多長時間,這個值始終如一,當我們在進行文件的下載上傳過程中,emule都是通過這個值來確定文件。

那麼什麼是userhash呢?

道理同上,當我們在第一次使用emule的時候,emule會自動生成一個值,這個值也是唯一的,它是我們在emule世界裡面的標志,只要你不卸載,不刪除config,你的userhash值也就永遠不變,積分制度就是通過這個值在起作用,emule裡面的積分保存,身份識別,都是使用這個值,而和你的id和你的用戶名無關,你隨便怎麼改這些東西,你的userhash值都是不變的,這也充分保證了公平性。其實他也是一個信息摘要,只不過保存的不是文件信息,而是我們每個人的信息。

那麼什麼是hash文件呢?

我們經常在emule日至裡面看到,emule正在hash文件,這里就是利用了hash演算法的文件校驗性這個功能了,文章前面已經說了一些這些功能,其實這部分是一個非常復雜的過程,目前在ftp,bt等軟體裡面都是用的這個基本原理,emule裡面是採用文件分塊傳輸,這樣傳輸的每一塊都要進行對比校驗,如果錯誤則要進行重新下載,這期間這些相關信息寫入met文件,直到整個任務完成,這個時候part文件進行重新命名,然後使用move命令,把它傳送到incoming文件裡面,然後met文件自動刪除,所以我們有的時候會遇到hash文件失敗,就是指的是met裡面的信息出了錯誤不能夠和part文件匹配,另外有的時候開機也要瘋狂hash,有兩種情況一種是你在第一次使用,這個時候要hash提取所有文件信息,還有一種情況就是上一次你非法關機,那麼這個時候就是要進行排錯校驗了。

關於hash的演算法研究,一直是信息科學裡面的一個前沿,尤其在網路技術普及的今天,他的重要性越來越突出,其實我們每天在網上進行的信息交流安全驗證,我們在使用的操作系統密鑰原理,裡面都有它的身影,特別對於那些研究信息安全有興趣的朋友,這更是一個打開信息世界的鑰匙,他在hack世界裡面也是一個研究的焦點。

5. 哈希表,求最小值

HashTable table1 = new HashTable();
HashTable table2 = new HashTable();
table1.put("one","1");
table2.put("one","2");
table1.put("two","1");
table2.put("two","2");
for (Iterator iter = table1.keySet().iterator();
iter.hasNext(); ) {
Object keyString = (Object) iter.next();
Object valueObject = table1.get(keyString);
int oneValue = Integer.parseInt((String)valueObject );
int twoValue = Integer.parseInt((String)table2.get(keyString) );
if(oneValue > twoValue){
System.out.println("KEY是"+keyString+"Value"+twoValue);
}else if(oneValue < twoValue){
System.out.println("KEY是"+keyString+"Value"+oneValue);
}else{
System.out.println("KEY是"+keyString+"兩值相等"+oneValue);
}
}

6. 高分懸賞 題目:哈希表查詢設計及實現

/*
(1)設計哈希表,該表應能夠容納50個英文單詞。
(2)對該哈希表進行查詢,實現對特定單詞的快速查詢,並顯示經過的節點內容
已經發到你郵箱里了 [email protected]
*/
#include <conio.h>
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define szNAME 80
#define HASH_ROOT 47 /*用於計算哈希地址的隨機數*/
#define szHASH 50 /*哈希表總長度*/
#define POPULATION 30 /*學生總數*/

/*哈希表結構體*/
struct THash {
int key; /*鑰匙碼*/
char name[10]; /*姓名*/
int depth; /*檢索深度*/
};

/*根據鑰匙碼和哈希根計算哈希地址*/
int GetHashAddress(int key, int root)
{
return key % root;
}/*end GetHashAddress*/

/*沖突地址計算,如果發現地址沖突,則用當前地址和鑰匙碼、哈希根重新生成一個新地址*/
int GetConflictAddress(int key, int address, int root)
{
int addr = address + key % 5 + 1;
return addr % root;
}/*end GetConflictAddress*/

/*根據字元串生成哈希鑰匙碼,這里的方法是將串內所有字元以數值形式求累加和*/
int CreateKey(char * name)
{
int key = 0;
unsigned char * n = (unsigned char *)name;
while(*n) key += *n++;
return key;
}/*end CreateKey*/

/*輸入一個名字,並返回哈希鑰匙碼*/
int GetName(char * name)
{
scanf("%s", name);
return CreateKey(name);
}/*end CreateKey*/

/*根據學生人數、長度和哈希根構造哈希表*/
struct THash * CreateNames(int size, int root, int population)
{
int i =0, key = 0, addr = 0, depth = 0; char name[10];
struct THash * h = 0, *hash = 0;

/*哈希根和長度不能太小*/
if(size < root || root < 2) return 0;

/*根據哈希表長度構造一個空的哈希表*/
hash = (struct THash *)malloc(sizeof(struct THash) * size);

/*將整個表清空*/
memset(hash, 0, sizeof(struct THash) * size);

for(i = 0; i < population; i++) {
/*首先產生一個隨機的學生姓名,並根據姓名計算哈希鑰匙碼,再根據鑰匙碼計算地址*/
key = GetName(name);
addr = GetHashAddress(key, root);
h = hash + addr;
if (h->depth == 0) { /*如果當前哈希地址沒有被佔用,則存入數據*/
h->key = key;
strcpy(h->name , name);
h->depth ++;
continue;
}/*end if*/
/*如果哈希地址已經被佔用了,就是說有沖突,則尋找一個新地址,直到沒有被佔用*/
depth = 0;
while(h->depth ) {
addr = GetConflictAddress(key, addr, root);
h = hash + addr;
depth ++;
}/*end while*/
/*按照新地址存放數據,同時記錄檢索深度*/
h->key = key;
strcpy(h->name , name);
h->depth = depth + 1;
}/*next*/
return hash;
}/*end CreateNames*/

/*在哈希表中以特定哈希根查找一個學生的記錄*/
struct THash * Lookup(struct THash * hash, char * name, int root)
{
int key = 0, addr = 0; struct THash * h = 0;
/*不接受空表和空名稱*/
if(!name || !hash) return 0;
key = CreateKey(name);
addr = GetHashAddress(key, root);
h = hash + addr;
/*如果結果不正確表示按照沖突規則繼續尋找*/
while(strcmp(h->name , name)) {
addr = GetConflictAddress(key, addr, root);
h = hash + addr;
if(h->key == 0) return 0;
}/*end while*/
return hash + addr;
}/*end Lookup*/

/*根據一條哈希表記錄列印該記錄的學生信息*/
void Print(struct THash * record)
{
if (!record) {
printf("【查無此人】\n");
return ;
}/*end if*/
if(record->depth)
printf("【鑰匙碼】%04d\t【姓名】%s\t【檢索深度】%d\n", record->key, record->name, record->depth );
else
printf("【空記錄】\n");
/*end if*/
}/*end Print*/

/*列印學生花名冊*/
void Display(struct THash * hash, int size)
{
struct THash * h = 0;
if (!hash || size < 1) return ;
printf("學生花名冊:\n");
printf("--------------------\n");
for(h = hash; h < hash + size; h++) {
printf("【地址】%d\t", h - hash);
Print(h);
}/*next*/
printf("--------------------\n");
}/*end Display*/

/*主函數,程序入口*/
int main(void)
{
/*哈希表變數聲明*/
struct THash * hash = 0, * h = 0;
int cmd = 0; /*命令*/
char name[10]; /*學生姓名*/

/*生成30個學生用的哈希表*/
hash = CreateNames(szHASH, HASH_ROOT, POPULATION);
for(;;) {
printf("哈希表展示:1-顯示哈希表;2-檢索姓名;其他任意鍵退出:\n");
cmd = getch();
cmd -= '0';
switch(cmd) {
case 1: Display(hash, szHASH); break;
case 2:
printf("請輸入要檢索的學生姓名:");
scanf("%s", name);
h = Lookup(hash, name, HASH_ROOT);
printf("【地址】%d\t", h - hash);
Print(h);
break;
default:
free(hash);
return 0;
}/*end case*/
}/*next*/
return 0;
}/*end main*/

7. 哈希表的設計與實現(線性探測再散列法解決沖突)

散列表(Hash table,也叫哈希表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫做散列函數,存放記錄的數組叫做散列表。
[編輯本段]基本概念
* 若結構中存在關鍵字和K相等的記錄,則必定在f(K)的存儲位置上。由此,不需比較便可直接取得所查記錄。稱這個對應關系f為散列函數(Hash function),按這個思想建立的表為散列表。 * 對不同的關鍵字可能得到同一散列地址,即key1≠key2,而f(key1)=f(key2),這種現象稱沖突。具有相同函數值的關鍵字對該散列函數來說稱做同義詞。綜上所述,根據散列函數H(key)和處理沖突的方法將一組關鍵字映象到一個有限的連續的地址集(區間)上,並以關鍵字在地址集中的「象」 作為記錄在表中的存儲位置,這種表便稱為散列表,這一映象過程稱為散列造表或散列,所得的存儲位置稱散列地址。 * 若對於關鍵字集合中的任一個關鍵字,經散列函數映象到地址集合中任何一個地址的概率是相等的,則稱此類散列函數為均勻散列函數(Uniform Hash function),這就是使關鍵字經過散列函數得到一個「隨機的地址」,從而減少沖突。
[編輯本段]常用的構造散列函數的方法
散列函數能使對一個數據序列的訪問過程更加迅速有效,通過散列函數,數據元素將被更快地定位ǐ 1. 直接定址法:取關鍵字或關鍵字的某個線性函數值為散列地址。即H(key)=key或H(key) = a•key + b,其中a和b為常數(這種散列函數叫做自身函數) 2. 數字分析法 3. 平方取中法 4. 折疊法 5. 隨機數法 6. 除留余數法:取關鍵字被某個不大於散列表表長m的數p除後所得的余數為散列地址。即 H(key) = key MOD p, p<=m。不僅可以對關鍵字直接取模,也可在折疊、平方取中等運算之後取模。對p的選擇很重要,一般取素數或m,若p選的不好,容易產生同義詞。
[編輯本段]處理沖突的方法
1. 開放定址法:Hi=(H(key) + di) MOD m, i=1,2,…, k(k<=m-1),其中H(key)為散列函數,m為散列表長,di為增量序列,可有下列三種取法: 1. di=1,2,3,…, m-1,稱線性探測再散列; 2. di=1^2, (-1)^2, 2^2,(-2)^2, (3)^2, …, ±(k)^2,(k<=m/2)稱二次探測再散列; 3. di=偽隨機數序列,稱偽隨機探測再散列。 == 2. 再散列法:Hi=RHi(key), i=1,2,…,k RHi均是不同的散列函數,即在同義詞產生地址沖突時計算另一個散列函數地址,直到沖突不再發生,這種方法不易產生「聚集」,但增加了計算時間。 3. 鏈地址法(拉鏈法) 4. 建立一個公共溢出區
[編輯本段]查找的性能分析
散列表的查找過程基本上和造表過程相同。一些關鍵碼可通過散列函數轉換的地址直接找到,另一些關鍵碼在散列函數得到的地址上產生了沖突,需要按處理沖突的方法進行查找。在介紹的三種處理沖突的方法中,產生沖突後的查找仍然是給定值與關鍵碼進行比較的過程。所以,對散列表查找效率的量度,依然用平均查找長度來衡量。 查找過程中,關鍵碼的比較次數,取決於產生沖突的多少,產生的沖突少,查找效率就高,產生的沖突多,查找效率就低。因此,影響產生沖突多少的因素,也就是影響查找效率的因素。影響產生沖突多少有以下三個因素: 1. 散列函數是否均勻; 2. 處理沖突的方法; 3. 散列表的裝填因子。 散列表的裝填因子定義為:α= 填入表中的元素個數 / 散列表的長度 α是散列表裝滿程度的標志因子。由於表長是定值,α與「填入表中的元素個數」成正比,所以,α越大,填入表中的元素較多,產生沖突的可能性就越大;α越小,填入表中的元素較少,產生沖突的可能性就越小。 實際上,散列表的平均查找長度是裝填因子α的函數,只是不同處理沖突的方法有不同的函數。 了解了hash基本定義,就不能不提到一些著名的hash演算法,MD5 和 SHA-1 可以說是目前應用最廣泛的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) SHA-1 及其他 SHA1是由NIST NSA設計為同DSA一起使用的,它對長度小於264的輸入,產生長度為160bit的散列值,因此抗窮舉(brute-force)性更好。SHA-1 設計時基於和MD4相同原理,並且模仿了該演算法。 那麼這些Hash演算法到底有什麼用呢? Hash演算法在信息安全方面的應用主要體現在以下的3個方面: (1) 文件校驗 我們比較熟悉的校驗演算法有奇偶校驗和CRC校驗,這2種校驗並沒有抗數據篡改的能力,它們一定程度上能檢測並糾正數據傳輸中的信道誤碼,但卻不能防止對數據的惡意破壞。 MD5 Hash演算法的"數字指紋"特性,使它成為目前應用最廣泛的一種文件完整性校驗和(Checksum)演算法,不少Unix系統有提供計算md5 checksum的命令。 (2) 數字簽名 Hash 演算法也是現代密碼體系中的一個重要組成部分。由於非對稱演算法的運算速度較慢,所以在數字簽名協議中,單向散列函數扮演了一個重要的角色。 對 Hash 值,又稱"數字摘要"進行數字簽名,在統計上可以認為與對文件本身進行數字簽名是等效的。而且這樣的協議還有其他的優點。 (3) 鑒權協議 如下的鑒權協議又被稱作挑戰--認證模式:在傳輸信道是可被偵聽,但不可被篡改的情況下,這是一種簡單而安全的方法。 MD5、SHA1的破解 2004年8月17日,在美國加州聖芭芭拉召開的國際密碼大會上,山東大學王小雲教授在國際會議上首次宣布了她及她的研究小組近年來的研究成果——對MD5、HAVAL-128、MD4和RIPEMD等四個著名密碼演算法的破譯結果。 次年二月宣布破解SHA-1密碼。
[編輯本段]實際應用
以上就是一些關於hash以及其相關的一些基本預備知識。那麼在emule裡面他具體起到什麼作用呢? 大家都知道emule是基於P2P (Peer-to-peer的縮寫,指的是點對點的意思的軟體), 它採用了"多源文件傳輸協議」(MFTP,the Multisource FileTransfer Protocol)。在協議中,定義了一系列傳輸、壓縮和打包還有積分的標准,emule 對於每個文件都有md5-hash的演算法設置,這使得該文件獨一無二,並且在整個網路上都可以追蹤得到。 什麼是文件的hash值呢? MD5-Hash-文件的數字文摘通過Hash函數計算得到。不管文件長度如何,它的Hash函數計算結果是一個固定長度的數字。與加密演算法不同,這一個Hash演算法是一個不可逆的單向函數。採用安全性高的Hash演算法,如MD5、SHA時,兩個不同的文件幾乎不可能得到相同的Hash結果。因此,一旦文件被修改,就可檢測出來。 當我們的文件放到emule裡面進行共享發布的時候,emule會根據hash演算法自動生成這個文件的hash值,他就是這個文件唯一的身份標志,它包含了這個文件的基本信息,然後把它提交到所連接的伺服器。當有他人想對這個文件提出下載請求的時候, 這個hash值可以讓他人知道他正在下載的文件是不是就是他所想要的。尤其是在文件的其他屬性被更改之後(如名稱等)這個值就更顯得重要。而且伺服器還提供了,這個文件當前所在的用戶的地址,埠等信息,這樣emule就知道到哪裡去下載了。 一般來講我們要搜索一個文件,emule在得到了這個信息後,會向被添加的伺服器發出請求,要求得到有相同hash值的文件。而伺服器則返回持有這個文件的用戶信息。這樣我們的客戶端就可以直接的和擁有那個文件的用戶溝通,看看是不是可以從他那裡下載所需的文件。 對於emule中文件的hash值是固定的,也是唯一的,它就相當於這個文件的信息摘要,無論這個文件在誰的機器上,他的hash值都是不變的,無論過了多長時間,這個值始終如一,當我們在進行文件的下載上傳過程中,emule都是通過這個值來確定文件。 那麼什麼是userhash呢? 道理同上,當我們在第一次使用emule的時候,emule會自動生成一個值,這個值也是唯一的,它是我們在emule世界裡面的標志,只要你不卸載,不刪除config,你的userhash值也就永遠不變,積分制度就是通過這個值在起作用,emule裡面的積分保存,身份識別,都是使用這個值,而和你的id和你的用戶名無關,你隨便怎麼改這些東西,你的userhash值都是不變的,這也充分保證了公平性。其實他也是一個信息摘要,只不過保存的不是文件信息,而是我們每個人的信息。 那麼什麼是hash文件呢? 我們經常在emule日誌裡面看到,emule正在hash文件,這里就是利用了hash演算法的文件校驗性這個功能了,文章前面已經說了一些這些功能,其實這部分是一個非常復雜的過程,目前在ftp,bt等軟體裡面都是用的這個基本原理,emule裡面是採用文件分塊傳輸,這樣傳輸的每一塊都要進行對比校驗,如果錯誤則要進行重新下載,這期間這些相關信息寫入met文件,直到整個任務完成,這個時候part文件進行重新命名,然後使用move命令,把它傳送到incoming文件裡面,然後met文件自動刪除,所以我們有的時候會遇到hash文件失敗,就是指的是met裡面的信息出了錯誤不能夠和part文件匹配,另外有的時候開機也要瘋狂hash,有兩種情況一種是你在第一次使用,這個時候要hash提取所有文件信息,還有一種情況就是上一次你非法關機,那麼這個時候就是要進行排錯校驗了。 關於hash的演算法研究,一直是信息科學裡面的一個前沿,尤其在網路技術普及的今天,他的重要性越來越突出,其實我們每天在網上進行的信息交流安全驗證,我們在使用的操作系統密鑰原理,裡面都有它的身影,特別對於那些研究信息安全有興趣的朋友,這更是一個打開信息世界的鑰匙,他在hack世界裡面也是一個研究的焦點。 一般的線性表、樹中,記錄在結構中的相對位置是隨機的即和記錄的關鍵字之間不存在確定的關系,在結構中查找記錄時需進行一系列和關鍵字的比較。這一類查找方法建立在「比較」的基礎上,查找的效率與比較次數密切相關。理想的情況是能直接找到需要的記錄,因此必須在記錄的存儲位置和它的關鍵字之間建立一確定的對應關系f,使每個關鍵字和結構中一個唯一的存儲位置相對應。因而查找時,只需根據這個對應關系f找到給定值K的像f(K)。若結構中存在關鍵字和K相等的記錄,則必定在f(K)的存儲位置上,由此不需要進行比較便可直接取得所查記錄。在此,稱這個對應關系f為哈希函數,按這個思想建立的表為哈希表(又稱為雜湊法或散列表)。 哈希表不可避免沖突(collision)現象:對不同的關鍵字可能得到同一哈希地址 即key1≠key2,而hash(key1)=hash(key2)。具有相同函數值的關鍵字對該哈希函數來說稱為同義詞(synonym)。 因此,在建造哈希表時不僅要設定一個好的哈希函數,而且要設定一種處理沖突的方法。可如下描述哈希表:根據設定的哈希函數H(key)和所選中的處理沖突的方法,將一組關鍵字映象到一個有限的、地址連續的地址集(區間)上並以關鍵字在地址集中的「象」作為相應記錄在表中的存儲位置,這種表被稱為哈希表。 對於動態查找表而言,1) 表長不確定;2)在設計查找表時,只知道關鍵字所屬范圍,而不知道確切的關鍵字。因此,一般情況需建立一個函數關系,以f(key)作為關鍵字為key的錄在表中的位置,通常稱這個函數f(key)為哈希函數。(注意:這個函數並不一定是數學函數) 哈希函數是一個映象,即:將關鍵字的集合映射到某個地址集合上,它的設置很靈活,只要這個地址集合的大小不超出允許范圍即可。 現實中哈希函數是需要構造的,並且構造的好才能使用的好。 用途:加密,解決沖突問題。。。。 用途很廣,比特精靈中就使用了哈希函數,你可 以自己看看。 具體可以學習一下數據結構和演算法的書。
[編輯本段]字元串哈希函數
(著名的ELFhash演算法) int ELFhash(char *key) return h%MOD; }

8. 數據結構哈希表,求大神,急急急

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 20
#define MAX_SIZE 20 //人名的最大長度
#define HASHSIZE 60 //定義表長
#define SUCCESS 1
#define UNSUCCESS -1
typedef int Status; //為現有類型添加一個同義字
typedef char NA[MAX_SIZE]; // typedef 掩飾數組類型
typedef struct //記錄
{
NA name;
NA xuehao; //關鍵字
NA tel;
}Stu; //查找表中記錄類型

typedef struct //建立哈希表
{
Stu *elem[HASHSIZE]; //數據元素存儲基址
int cou; //當前數據元素個數
int siz; //當前容量
}HashTable;

Status eq(NA x,NA y)
{
if(strcmp(x,y)==0)
return SUCCESS;
else return UNSUCCESS;
}

Status NUM_BER; //記錄的個數 全局變數
Status NUM_BER1;

void Create(Stu* a) //創建新的通訊錄
{
system("CLS"); //調用DOS命令CLS能夠清屏
int i;
FILE *fp1,*fp2;
if((fp1=fopen("record.txt","r"))!=NULL) //打開文件
{
fclose(fp1); //關閉文件
}
else
{
fp2=fopen("record.txt","w"); //如果不存在,就創建一個record.txt
fclose(fp2);
}
printf("\n輸入要添加的個數:\n");
scanf("%d",&NUM_BER);
for(i=0;i<NUM_BER;i++)
{
printf("請輸入第%d個記錄的姓名:\n",i+1);
scanf("%s",a[i].name);
printf("請輸入%d個記錄的學號:\n",i+1);
scanf("%s",a[i].xuehao);
printf("請輸入第%d個記錄的電話號碼:\n",i+1);
scanf("%s",a[i].tel);
}
getchar();
printf("添加成功!!!\n");

}

void getin(Stu * a) //錄入通訊錄的內容,傳入一個record的指針,然後針對這個指針指向的內存記錄進行操作
{int i;
system("cls"); //調用DOS命令CLS能夠清屏
printf("輸入要添加的個數:\n");
scanf("%d",&NUM_BER);
for(i=0;i<NUM_BER;i++)
{
printf("請輸入第%d個記錄的姓名:\n",i+1);
scanf("%s",a[i].name);
printf("請輸入%d個記錄的學號:\n",i+1);
scanf("%s",a[i].xuehao);
printf("請輸入第%d個記錄的電話號碼:\n",i+1);
scanf("%s",a[i].tel);
}
}
void output(Stu* a) //顯示輸入的用戶信息
{int i;
system("cls");
printf(" \n姓名\t學號\t\t電話號碼");
for( i=0;i<NUM_BER;i++)
printf("\n%s\t%s\t\t%s",a[i].name,a[i].xuehao,a[i].tel);
}
int Hash(NA name)
{
int i,m;
i = 1;
m=(int)name[0];//強制轉化成數字
while(name[i]!='\0')
{
m+=(int)name[i];
i++;
}
m=m%HASHSIZE;
return m;
}

Status collision(int p,int c) //沖突處理函數,採用二次探測法解決沖突 //二次探測法處理沖突
{
int i,q;
i=c/2+1;
while(i<HASHSIZE)
{
if(c%2==0)
{
c++;
q=(p+i*i)%HASHSIZE;
if(q>=0) return q;
else i=c/2+1;
}
else
{
q=(p-i*i)%HASHSIZE;
c++;
if(q>=0) return q;
else i=c/2+1;
}
}
return UNSUCCESS;
}

void CreateHash(HashTable* H,Stu* a) //建表,以人的姓名為關鍵字,建立相應的哈希表
{ int i,p=-1,c,pp;
system("cls");//若哈希地址沖突,進行沖突處理
for(i=0;i<NUM_BER+NUM_BER1;i++)
{
c=0;
p=Hash(a[i].name);
pp=p;
while(H->elem[pp]!=NULL)
{
pp=collision(p,c); //若哈希地址沖突,進行沖突處理
if(pp<0)
{
printf("第%d記錄無法解決沖突",i+1); //需要顯示沖突次數時輸出
continue; //無法解決沖突,跳入下一循環
}
}
H->elem[pp]=&(a[i]); //求得哈希地址,將信息存入
H->cou++;
printf("第%d個記錄沖突次數為%d。\n",i+1,c);
}
printf("\n建表完成!\n此哈希表容量為%d,當前表內存儲的記錄個數為%d.\n",HASHSIZE,H->cou);

}

void SearchHash(HashTable* H,int c) //在通訊錄里查找姓名關鍵字,c用來記錄沖突次數,若查找成功,顯示信息
{
int p,pp;NA NAME;
system("cls");
printf("\n請輸入要查找記錄的姓名:\n");
scanf("%s",NAME);
p=Hash(NAME);
pp=p;
while((H->elem[pp]!=NULL)&&(eq(NAME,H->elem[pp]->name)==-1))
pp=collision(p,c);
if(H->elem[pp]!=NULL&&eq(NAME,H->elem[pp]->name)==1)
{
printf("\n查找成功!\n查找過程沖突次數為%d.以下是您需要要查找的信息:\n\n",c);
printf("姓名:%s\n學號:%s\n電話號碼:%s\n",H->elem[pp]->name,H->elem[pp]->xuehao,H->elem[pp]->tel);
}
else printf("\n此人不存在,查找不成功!\n");

}

void Modify(HashTable* H,int c) //在通訊錄里修改某人信息
{
int p,pp;NA NAME;
system("cls");
printf("\n請輸入要修改記錄的姓名:\n");
scanf("%s",NAME);
p=Hash(NAME);
pp=p;
while((H->elem[pp]!=NULL)&&(eq(NAME,H->elem[pp]->tel)==-1))
pp=collision(p,c);
if(H->elem[pp]!=NULL&&eq(NAME,H->elem[pp]->tel)==1)
{
printf("\n以下是您需要修改的信息:");
printf("姓名:%s\n學號:%s\n電話號碼:%s\n",H->elem[pp]->name,H->elem[pp]->xuehao,H->elem[pp]->tel);
(H->elem)[pp]->tel[0]='\0';
printf("請輸入修改後記錄的姓名:\n");
scanf("%s",H->elem[pp]->name);
printf("請輸入修改後記錄的學號:\n");
scanf("%s",H->elem[pp]->xuehao);
printf("請輸入修改後記錄的電話號碼:\n");
scanf("%s",H->elem[pp]->tel);
printf("修改成功!");
}
else
printf("\n此人不存在,修改不成功!\n");
}

void Delete(HashTable* H,int c) //在通訊錄里查找姓名關鍵字,若查找成功,顯示信息然後刪除
{
int m,p,pp;NA str;
m=0;
system("cls");
printf("\n請輸入要刪除記錄的姓名:\n");
m++;
scanf("%s",str);
p=Hash(str);
pp=p;
while((H->elem[pp]!=NULL)&&(eq(str,H->elem[pp]->name)==-1))
pp=collision(p,c);
if(H->elem[pp]!=NULL&&eq(str,H->elem[pp]->name)==1)
{
printf("\n以下是您需要要刪除的信息:\n\n",c);
printf("姓名:%s\n學號:%s\n電話號碼:%s\n",H->elem[pp]->name,H->elem[pp]->xuehao,H->elem[pp]->tel);
(H->elem)[pp]->name[0]='\0';
printf("刪除成功!!!");
}
else
printf("\n此人不存在,刪除不成功!\n");
}
void Save(HashTable * H) //將記錄保存到指定文件
{
system("CLS");
int i;
FILE* fp;
if((fp=fopen("record.txt","w"))!=NULL)
{
fprintf(fp,"==================== 班級通訊錄 ===================\n");
for(i=0;i<HASHSIZE;i++)
{
if((H->elem)[i]!='\0')
{
fprintf(fp,"學生姓名:%s\n",H->elem[i]->name);
fprintf(fp,"學生學號:%s\n",H->elem[i]->xuehao);
fprintf(fp,"學生電話號碼:%s\n",H->elem[i]->tel);
fprintf(fp,"***********************************************\n");
}
}
fclose(fp);
printf("==================== 班級通訊錄 ===================\n");
printf("\n\n恭喜你!!成功儲存,你能在record.txt找到相應紀錄\n");
system("pause");
}
else
{
printf("抱歉,保存記錄失敗!!");
system("pause");
}
}

int main()
{
Stu a[MAXSIZE];
int c,flag=1,i=0;
HashTable *H;
H=(HashTable*)malloc(sizeof(HashTable));
for(i=0;i<HASHSIZE;i++)
{
H->elem[i]=NULL;
H->siz=HASHSIZE;
H->cou=0;
}
while (1)
{ int num;

printf("\n");
printf("\n***************************班級通訊錄****************************");
printf("\n* 【1】. 創建用戶信息 *");
printf("\n* 【2】. 添加用戶信息 *");
printf("\n* 【3】. 顯示所有用戶信息 *");
printf("\n* 【4】. 以姓名建立哈希表(二次探測法解決沖突)*");
printf("\n* 【5】. 查找用戶信息 *");
printf("\n* 【6】. 刪除用戶信息 *");
printf("\n* 【7】. 修改用戶信息 *");
printf("\n* 【8】. 保存 *");
printf("\n* 【9】. 退出程序 *");
printf("\n*****************************************************************");
printf("\n");
printf("\n* 溫馨提示: *");
printf("\n* 進行4、5、6操作前 請先輸出3 *");
printf("\n*****************************************************************");
printf("\n請輸入一個任務選項>>>");
printf("\n");
scanf("%d",&num);
switch(num)
{
case 1:Create(a) ;break;
case 2:getin(a); break;
case 3:output(a); break;
case 4:CreateHash(H,a); break;
case 5:c=0;SearchHash(H,c); break;
case 6:c=0;Delete(H,c); break;
case 7:c=0;Modify(H,c); break;
case 8:Save(H); break;
case 9:return 0; break;
default:
printf("輸入錯誤,請重新輸入!");
printf("\n");
}
}
system("pause");
return 0;
}

9. 哈希表的實際應用

以上就是一些關於hash以及其相關的一些基本預備知識。那麼在emule裡面他具體起到什麼作用呢?
大家都知道emule是基於P2P (Peer-to-peer的縮寫,指的是對等連接的軟體), 它採用了多源文件傳輸協議」(MFTP,the Multisource FileTransfer Protocol)。在協議中,定義了一系列傳輸、壓縮和打包還有積分的標准,emule 對於每個文件都有md5-hash的演算法設置,這使得該文件獨一無二,並且在整個網路上都可以追蹤得到。
什麼是文件的hash值呢?
MD5-Hash-文件的數字文摘通過Hash函數計算得到。不管文件長度如何,它的Hash函數計算結果是一個固定長度的數字。與加密演算法不同,這一個Hash演算法是一個不可逆的單向函數。採用安全性高的Hash演算法,如MD5、SHA時,兩個不同的文件幾乎不可能得到相同的Hash結果。因此,一旦文件被修改,就可檢測出來。
當我們的文件放到emule裡面進行共享發布的時候,emule會根據hash演算法自動生成這個文件的hash值,他就是這個文件唯一的身份標志,它包含了這個文件的基本信息,然後把它提交到所連接的伺服器。當有他人想對這個文件提出下載請求的時候, 這個hash值可以讓他人知道他正在下載的文件是不是就是他所想要的。尤其是在文件的其他屬性被更改之後(如名稱等)這個值就更顯得重要。而且伺服器還提供了,這個文件當前所在的用戶的地址,埠等信息,這樣emule就知道到哪裡去下載了。
一般來講我們要搜索一個文件,emule在得到了這個信息後,會向被添加的伺服器發出請求,要求得到有相同hash值的文件。而伺服器則返回持有這個文件的用戶信息。這樣我們的客戶端就可以直接的和擁有那個文件的用戶溝通,看看是不是可以從他那裡下載所需的文件。
對於emule中文件的hash值是固定的,也是唯一的,它就相當於這個文件的信息摘要,無論這個文件在誰的機器上,他的hash值都是不變的,無論過了多長時間,這個值始終如一,當我們在進行文件的下載上傳過程中,emule都是通過這個值來確定文件。
那麼什麼是userhash呢?
道理同上,當我們在第一次使用emule的時候,emule會自動生成一個值,這個值也是唯一的,它是我們在emule世界裡面的標志,只要你不卸載,不刪除config,你的userhash值也就永遠不變,積分制度就是通過這個值在起作用,emule裡面的積分保存,身份識別,都是使用這個值,而和你的id和你的用戶名無關,你隨便怎麼改這些東西,你的userhash值都是不變的,這也充分保證了公平性。其實他也是一個信息摘要,只不過保存的不是文件信息,而是我們每個人的信息。
那麼什麼是hash文件呢?
我們經常在emule日誌裡面看到,emule正在hash文件,這里就是利用了hash演算法的文件校驗性這個功能了,文章前面已經說了一些這些功能,其實這部分是一個非常復雜的過程,在ftp,bt等軟體裡面都是用的這個基本原理,emule裡面是採用文件分塊傳輸,這樣傳輸的每一塊都要進行對比校驗,如果錯誤則要進行重新下載,這期間這些相關信息寫入met文件,直到整個任務完成,這個時候part文件進行重新命名,然後使用move命令,把它傳送到incoming文件裡面,然後met文件自動刪除,所以我們有的時候會遇到hash文件失敗,就是指的是met裡面的信息出了錯誤不能夠和part文件匹配,另外有的時候開機也要瘋狂hash,有兩種情況一種是你在第一次使用,這個時候要hash提取所有文件信息,還有一種情況就是上一次你非法關機,那麼這個時候就是要進行排錯校驗了。
關於hash的演算法研究,一直是信息科學裡面的一個前沿,尤其在網路技術普及的今天,他的重要性越來越突出,其實我們每天在網上進行的信息交流安全驗證,我們在使用的操作系統密鑰原理,裡面都有它的身影,特別對於那些研究信息安全有興趣的朋友,這更是一個打開信息世界的鑰匙,他在hack世界裡面也是一個研究的焦點。
一般的線性表、樹中,記錄在結構中的相對位置是隨機的即和記錄的關鍵字之間不存在確定的關系,在結構中查找記錄時需進行一系列和關鍵字的比較。這一類查找方法建立在「比較」的基礎上,查找的效率與比較次數密切相關。理想的情況是能直接找到需要的記錄,因此必須在記錄的存儲位置和它的關鍵字之間建立一確定的對應關系f,使每個關鍵字和結構中一個唯一的存儲位置相對應。因而查找時,只需根據這個對應關系f找到給定值K的像f(K)。若結構中存在關鍵字和K相等的記錄,則必定在f(K)的存儲位置上,由此不需要進行比較便可直接取得所查記錄。在此,稱這個對應關系f為哈希函數,按這個思想建立的表為哈希表(又稱為雜湊法或散列表)。
哈希表不可避免沖突(collision)現象:對不同的關鍵字可能得到同一哈希地址 即key1≠key2,而hash(key1)=hash(key2)。具有相同函數值的關鍵字對該哈希函數來說稱為同義詞(synonym)。因此,在建造哈希表時不僅要設定一個好的哈希函數,而且要設定一種處理沖突的方法。可如下描述哈希表:根據設定的哈希函數H(key)和所選中的處理沖突的方法,將一組關鍵字映象到一個有限的、地址連續的地址集(區間)上並以關鍵字在地址集中的「象」作為相應記錄在表中的存儲位置,這種表被稱為哈希表。
對於動態查找表而言,1) 表長不確定;2)在設計查找表時,只知道關鍵字所屬范圍,而不知道確切的關鍵字。因此,一般情況需建立一個函數關系,以f(key)作為關鍵字為key的錄在表中的位置,通常稱這個函數f(key)為哈希函數。(注意:這個函數並不一定是數學函數)
哈希函數是一個映象,即:將關鍵字的集合映射到某個地址集合上,它的設置很靈活,只要這個地址集合的大小不超出允許范圍即可。
現實中哈希函數是需要構造的,並且構造的好才能使用的好。
用途:加密,解決沖突問題。
用途很廣,比特精靈中就使用了哈希函數,你可以自己看看。
具體可以學習一下數據結構和演算法的書。

10. 求大神細致的介紹下哈希表和循環變數具體的使用方法。

哈希表就是用來存儲數據的地方,跟變數的作用類似,變數能做的哈希表也能做,兩者效率差不多。

舉個例子,游戲開始時記錄玩家1初始的黃金、木材和人口,以後不管什麼時候,輸入1就顯示這些數據:

記錄時注意目錄和標簽分別用不同的數字表示。

閱讀全文

與哈希表命令相關的資料

熱點內容
標志307的壓縮比是多少 瀏覽:633
伺服器啟動為什麼叫三聲 瀏覽:995
追風箏的人英文pdf 瀏覽:936
解壓小熊手機殼 瀏覽:346
成都市區建成面積演算法 瀏覽:660
智能家居單片機 瀏覽:97
買男裝用什麼app好 瀏覽:855
文件夾合並了怎麼拆開 瀏覽:260
波段副圖源碼無未來函數 瀏覽:89
livecn伺服器地址 瀏覽:259
程序員這個工作真的很吃香嗎 瀏覽:847
程序員和數學分析師待遇 瀏覽:681
壓縮氣彈簧怎麼拆 瀏覽:324
華為公有雲伺服器添加虛擬ip 瀏覽:211
程序員和運營哪個累 瀏覽:27
抖音安卓信息提示音怎麼設置 瀏覽:456
光速虛擬機的共享文件夾 瀏覽:251
程序員培訓機構發的朋友圈真實性 瀏覽:744
天乾地支簡單演算法 瀏覽:299
下載個壓縮文件 瀏覽:300