上面的代碼,展示了JAVA如何進(jìn)行HASH鍵值的存儲(chǔ),其中dreamforce是key,me代表value,這個(gè)key在放入 hashtable時(shí),會(huì)進(jìn)行hash加密轉(zhuǎn)換成hash碼,但是知道HASH加密算法的都知道,hash密文和hash明文絕對(duì)會(huì)存在一對(duì)多的關(guān)系,也就是說(shuō)現(xiàn)實(shí)生活中一定會(huì)有幾條數(shù)據(jù)hash加密后產(chǎn)生的hash值是一樣的,這是必然的結(jié)果。那么hash就從此不再安全了嗎?其實(shí)不然,只是說(shuō)這種必然的概率相當(dāng)?shù)男?,同時(shí)我們?cè)谶M(jìn)行hash算法的時(shí)候也一定要會(huì)使這種必然事件的概率降到最低,這才是一個(gè)極好的hash加密算法.

密碼學(xué)不是我的專長(zhǎng),所以我就點(diǎn)到為止,那么一旦這種必然條件觸發(fā)后,就會(huì)引起了所謂的碰撞:

這種碰撞的出現(xiàn)要滿足兩個(gè)條件,key的真實(shí)值必須要不同,因?yàn)橄嗤膋ey值會(huì)被hash表給過(guò)濾掉,其二就是key值的hashcode一定要一樣,舉例說(shuō)明:

在JAVA中,Aa 和 BB這兩個(gè)值的hashcode是一樣的,都是2112, 有興趣的同學(xué)可以試試

那么如果我進(jìn)下以下的編碼,大家會(huì)看到一個(gè)很詭異的事情:

通過(guò)調(diào)試,你們可以看到不一樣的地方:

在上圖中,你們可以看到。table中,只有兩條記錄存在 (BB=me, dreamforce=me),按道理來(lái)說(shuō),應(yīng)該是三條,那么有一條記錄(Aa=dreamforce)去了哪里了?

通過(guò)上圖,大家應(yīng)該恍然大悟了,那一條記錄并沒(méi)有消失,而是變成了鏈表結(jié)構(gòu)追加到了key=BB 這條記錄的下一個(gè)節(jié)點(diǎn)之上。。這樣就打破了hashtable的結(jié)構(gòu),如果有N條這樣的碰撞出現(xiàn),那么hashTable的效率也將蕩然無(wú)存了.數(shù)據(jù)就成了鏈表結(jié)構(gòu),而這時(shí)要獲取一個(gè)在鏈表之上的節(jié)點(diǎn)的value,就會(huì)進(jìn)行N次迭代進(jìn)行獲取,那么算法效率就從o(1)變成了o(n)……..這……

2.拒絕服務(wù)式攻擊

接著上面闡述了hashTable的碰撞原理后,各位同學(xué)們也應(yīng)該了解了這個(gè)拒絕服務(wù)式攻擊了吧,其實(shí)就是因?yàn)檫@個(gè)hashTable的漏洞的存在,如果有人通過(guò)傳遞精心設(shè)計(jì)好的可以產(chǎn)生碰撞的超大數(shù)據(jù),那么就會(huì)導(dǎo)致服務(wù)器不斷的進(jìn)行迭代讀取,CPU一下子就會(huì)被全額占滿,這是相當(dāng)恐怖的。有數(shù)據(jù)說(shuō),10kb的數(shù)據(jù)量就會(huì)導(dǎo)致一個(gè)i7的CPU馬上占用率飆升100%,本人沒(méi)有試過(guò),但也相信應(yīng)該差不多..

3.如何是好?

關(guān)于tomcat 以及微軟的解決之道就是很變通的告知大家,將請(qǐng)求參數(shù)據(jù)緩存值設(shè)小,也就是說(shuō),一次性的請(qǐng)求量不會(huì)導(dǎo)致CPU被全部占滿。。。其實(shí)這也是無(wú)奈之舉。

除此之外,就是設(shè)計(jì)好HASH算法,一定要保證必然碰撞事件的概率降低,也就是說(shuō)提高生產(chǎn)位數(shù),帶來(lái)的痛苦就是請(qǐng)求效率降低。各有取舍吧,魚與熊掌不可兼得.

做好異常檢測(cè),不要來(lái)者不拒,還是要理性的區(qū)分正常與惡意的數(shù)據(jù)請(qǐng)求.

分享到

huanghui

相關(guān)推薦