hash是什么?
? 最近讀關于php內核的資料,發現php中 在實現變量以及數據類型的實現中大量使用哈希算法,并且非常細致做出了很多優秀的細節設計。比如:在 zend.hash.h 中
static inline ulong zend_inline_hash_func(char *arKey, uint nKeyLength) {register ulong hash = 5381;/* variant with the hash unrolled eight times */for (; nKeyLength >= 8; nKeyLength -= 8) {hash = ((hash << 5) + hash) + *arKey++;hash = ((hash << 5) + hash) + *arKey++;hash = ((hash << 5) + hash) + *arKey++;hash = ((hash << 5) + hash) + *arKey++;hash = ((hash << 5) + hash) + *arKey++;hash = ((hash << 5) + hash) + *arKey++;hash = ((hash << 5) + hash) + *arKey++;hash = ((hash << 5) + hash) + *arKey++;}switch (nKeyLength) {case 7: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 6: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 5: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 4: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 3: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 2: hash = ((hash << 5) + hash) + *arKey++; /* fallthrough... */case 1: hash = ((hash << 5) + hash) + *arKey++; break;case 0: break; EMPTY_SWITCH_DEFAULT_CASE()}return hash; }相比較常用的 times 33 算法,會快一些了;
(相對web開發角度而言,我用自己的話來概括下 哈希)哈希是一種做法的總稱,這種做法指的就是 將一個字串(也可以說是數據)進行雜糅,得出一個定長的另一個字串(也可以說另一個數據),然后我們就可以用省的字串來 代替原來的字串了,就有指紋驗證的特征了。
? ? 目前已經有算法去實現這種做法了,比如:md5,sha1等等,使用算法去達到 不可逆,不重復的目的,當然這不是絕對的,只是很小很小概率上不重復不可逆,換句話說,就是目前你窮盡你所有的計算資源以及時間去也很難去逆轉。
? ?我認為hash算法是 很美妙的工具,他讓數據在傳輸過程中真正有了保密性,而且好多web開發的校驗過程都有使用它,下面來一段比較專業術語來描述吧,
抗碰撞能力:對于任意兩個不同的數據塊,其hash值相同的可能性極小;對于一個給定的數據塊,找到和它hash值相同的數據塊極為困難。
抗篡改能力:對于一個數據塊,哪怕只改動其一個比特位,其hash值的改動也會非常大。
在用到hash進行管理的數據結構中,比如hashmap,hash值(key)存在的目的是加速鍵值對的查找,key的作用是為了將元素適當地放在各個桶里,對于抗碰撞的要求沒有那么高。換句話說,hash出來的key,只要保證value大致均勻的放在不同的桶里就可以了。但整個算法的set性能,直接與hash值產生的速度有關,所以這時候的hash值的產生速度就尤為重要,以JDK中的String.hashCode()方法為例:
public int hashCode() { int h = hash; //hash default value : 0 if (h == 0 && value.length > 0) { //value : char storage char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
很簡潔的一個乘加迭代運算,在不少的hash算法中,使用的是異或+加法進行迭代,速度和前者差不多。
在密碼學中,hash算法的作用主要是用于消息摘要和簽名,換句話說,它主要用于對整個消息的完整性進行校驗。舉個例子,我們登陸知乎的時候都需要輸入密碼,那么知乎如果明文保存這個密碼,那么黑客就很容易竊取大家的密碼來登陸,特別不安全。那么知乎就想到了一個方法,使用hash算法生成一個密碼的簽名,知乎后臺只保存這個簽名值。由于hash算法是不可逆的,那么黑客即便得到這個簽名,也絲毫沒有用處;而如果你在網站登陸界面上輸入你的密碼,那么知乎后臺就會重新計算一下這個hash值,與網站中儲存的原hash值進行比對,如果相同,證明你擁有這個賬戶的密碼,那么就會允許你登陸。銀行也是如此,銀行是萬萬不敢保存用戶密碼的原文的,只會保存密碼的hash值而而已。哈希算法并不是一個特定的算法而是一類算法的統稱。哈希算法也叫散列算法,一般來說滿足這樣的關系:f(data)=key,輸入任意長度的data數據,經過哈希算法處理后輸出一個定長的數據key。同時這個過程是不可逆的,無法由key逆推出data。
如果是一個data數據集,經過哈希算法處理后得到key的數據集,然后將keys與原始數據進行一一映射就得到了一個哈希表。一般來說哈希表M符合M[key]=data這種形式。
哈希表的好處是當原始數據較大時,我們可以用哈希算法處理得到定長的哈希值key,那么這個key相對原始數據要小得多。我們就可以用這個較小的數據集來做索引,達到快速查找的目的。
稍微想一下就可以發現,既然輸入數據不定長,而輸出的哈希值卻是固定長度的,這意味著哈希值是一個有限集合,而輸入數據則可以是無窮多個。那么建立一對一關系明顯是不現實的。所以"碰撞"(不同的輸入數據對應了相同的哈希值)是必然會發生的,所以一個成熟的哈希算法會有較好的抗沖突性。同時在實現哈希表的結構時也要考慮到哈希沖突的問題。
密碼上常用的MD5,SHA都是哈希算法,因為key的長度(相對大家的密碼來說)較大所以碰撞空間較大,有比較好的抗碰撞性,所以常常用作密碼校驗。
?
轉載于:https://www.cnblogs.com/guixiaoming/p/7805025.html
總結
- 上一篇: 如何有效地管理测试用例
- 下一篇: openstack+essex+quan