李立亞,吳 麗,遲榮華
(無(wú)錫科技職業(yè)學(xué)院人工智能學(xué)院,江蘇 無(wú)錫 214028)
在計(jì)算機(jī)數(shù)據(jù)處理技術(shù)中,哈希算法將任意長(zhǎng)度數(shù)據(jù)塊映射為較短的固定長(zhǎng)度的二進(jìn)制值,即哈希值。只要是更改數(shù)據(jù)塊的任何字節(jié),都會(huì)產(chǎn)生不同的哈希值,反向找到同一哈希值的不同輸入,在計(jì)算上代價(jià)巨大。因此,哈希算法廣泛應(yīng)用在數(shù)據(jù)的完整性檢驗(yàn)、數(shù)據(jù)快速查找、構(gòu)造安全的數(shù)據(jù)結(jié)構(gòu)等。
哈希算法的實(shí)現(xiàn)方式有加減法、位運(yùn)算、乘法除法、查表、混合實(shí)現(xiàn)等,不同實(shí)現(xiàn)方式在運(yùn)行速度和哈希效果上有所差異。比較常見的算法有MD5、SHA-1、BKDRHash、APHash 等。不同的哈希算法有不同的特性,適用不同的場(chǎng)合。文獻(xiàn)[1]對(duì)哈希函數(shù)的迭代結(jié)構(gòu)和壓縮函數(shù)進(jìn)行了研究,可以構(gòu)造安全性較高的哈希算法。文獻(xiàn)[2]在哈希計(jì)算過(guò)程中加入了隨機(jī)性,提高了哈希算法的安全性。文獻(xiàn)[3]利用二元方程構(gòu)造了一種哈希算法,具備較好的效果和性能。文獻(xiàn)[4]利用明文信息進(jìn)行迭代次數(shù)控制,增加了隨機(jī)性。文獻(xiàn)[5]針對(duì)物聯(lián)網(wǎng)設(shè)備設(shè)計(jì)了一種輕量級(jí)哈希函數(shù),在安全和性能上做了折中,犧牲部分性能,提高安全性。文獻(xiàn)[6]使用字典法構(gòu)造了一種完美哈希函數(shù),效果較好,但算法復(fù)雜和對(duì)工作空間要求高。文獻(xiàn)[7]從理論上證明了采用異或運(yùn)算和位移運(yùn)算能夠提供較好的哈希值隨機(jī)特性,并用這兩種基本操作,提出了異或循環(huán)哈希算法,在性能和效率上有優(yōu)勢(shì)。文獻(xiàn)[8]設(shè)計(jì)了一種基于異或運(yùn)算、并加入偽隨機(jī)移位的哈希函數(shù),應(yīng)用在以TCP 網(wǎng)絡(luò)連接管理的哈希表中,取得了較好的效果。
本文通過(guò)移位、取反、和加法加速數(shù)據(jù)混淆過(guò)程,設(shè)計(jì)了一種快速字符串哈希算法,算法結(jié)構(gòu)簡(jiǎn)明、編程實(shí)現(xiàn)簡(jiǎn)單。與文獻(xiàn)[9]提出的BKDRHash 算法相比,本算法在效果上相當(dāng)?shù)那闆r下,速度上具有10%左右優(yōu)勢(shì)。
采用的混淆計(jì)算手段越多、混淆過(guò)程的計(jì)算參數(shù)調(diào)整越靈活、越容易獲得較好的哈希效果,但計(jì)算過(guò)多又會(huì)影響算法性能。本算法在位混淆設(shè)計(jì)上,使用短周期計(jì)算指令的操作完成,減少計(jì)算數(shù)量。
本文哈希算法以位運(yùn)算、加法為基礎(chǔ)構(gòu)造。如圖1 所示。中間結(jié)果左移、取反,然后加字符(改進(jìn)算法再加中間一次結(jié)果),循環(huán)往復(fù),直至處理完畢所有數(shù)據(jù),計(jì)算出Hash結(jié)果。通過(guò)實(shí)驗(yàn)測(cè)試搜索左移位數(shù)因子,左移7位效果最佳。
算法設(shè)計(jì)上分為基本型和改進(jìn)型兩種:基本型算法速度更快,混淆效果稍弱,速度更快。改進(jìn)型算法再加一次中間哈希碼,效果更好,速度稍弱。
本算法計(jì)算過(guò)程使用的數(shù)據(jù)位字長(zhǎng)基于標(biāo)準(zhǔn)字長(zhǎng),與CPU 字長(zhǎng)、或程序設(shè)計(jì)語(yǔ)言支持的字長(zhǎng)一致,比如32位、64位。設(shè)計(jì)思路:①移位和取反只使用一次,移位和取反可以迅速地改變數(shù)據(jù)位,但對(duì)數(shù)據(jù)位的混淆功能有限;②最多使用兩次加法操作,進(jìn)行混淆。
計(jì)算次序設(shè)計(jì):移位操作會(huì)損失數(shù)據(jù)位,取反操作僅對(duì)位取反,加法操作進(jìn)行位混淆擴(kuò)散功能,因此按先移位、再取反,最后做加法的次序進(jìn)行計(jì)算。
本文采取對(duì)中間結(jié)果進(jìn)行移位取反,再加字符串中字符的方案設(shè)計(jì)。移位操作將低位補(bǔ)0,取反時(shí),這些位變?yōu)?,從而增加1 的數(shù)量。如此,在做加法時(shí)可以獲得較好的混淆擴(kuò)散效果。
計(jì)算公式為:中間哈希碼=中間哈希碼左移7位后取反+字符+中間哈希碼。
基本型混淆擴(kuò)散過(guò)程如圖1所示。
圖1 混淆擴(kuò)散過(guò)程圖
本算法對(duì)空間需求為幾個(gè)整型變量的空間。
計(jì)算復(fù)雜度,每輪迭代都有中間結(jié)果移位、取反、加操作運(yùn)算,計(jì)算復(fù)雜度為O(N+N+N)。與BKDR 算法相比,BKDR 算法計(jì)算復(fù)雜度為O(N+N),但BKDR中使用了乘法,乘法指令周期數(shù)遠(yuǎn)大于位運(yùn)算和加法。因此本算法在指令周期數(shù)上具有優(yōu)勢(shì)。
BKDR快速哈希算法,在速度、哈希效果上都非常優(yōu)秀,該算法來(lái)自于Brian Kernighan 和Dennis Ritchie 合著的《The C Programming Language》專著。本文以該算法為參照對(duì)象進(jìn)行對(duì)比測(cè)試。
兩個(gè)算法均用VC#進(jìn)行程序編碼。BKDR快速哈希算法選用種子值131,算法代碼如下:
⑴性能測(cè)試
分別用大小兩種數(shù)據(jù)塊來(lái)測(cè)試性能:①測(cè)試20個(gè)字長(zhǎng)的數(shù)據(jù)塊1000 萬(wàn)次;②測(cè)試1000 萬(wàn)個(gè)字長(zhǎng)的數(shù)據(jù)塊100次。
分別在WIN7 系統(tǒng)和WIN10 系統(tǒng)兩臺(tái)PC 上進(jìn)行了測(cè)試。WIN7 系統(tǒng)配置為Intel i5-2400 CPU,主頻為3.1GHz,最大睿頻3.4Ghz。WIN10 系統(tǒng)配置為Intel i5-8400 CPU,主頻為2.80GHz,最大睿頻4.0Ghz。
在兩個(gè)系統(tǒng)平臺(tái)上測(cè)試過(guò)程中,發(fā)現(xiàn)WIN7 系統(tǒng)平臺(tái)測(cè)試結(jié)果比較穩(wěn)定,變化很小。而WIN10系統(tǒng)平臺(tái)測(cè)試結(jié)果穩(wěn)定性較差,變化較大。推測(cè)是WIN7 平臺(tái)CPU 睿頻范圍小、WIN10 平臺(tái)CPU 睿頻范圍大,測(cè)試過(guò)程中CPU睿頻程度不同導(dǎo)致測(cè)試結(jié)果穩(wěn)定性不同。
經(jīng)過(guò)多次測(cè)試,選出偏離度較小的樣本數(shù)據(jù)做為測(cè)試結(jié)果,如表1和表2所示。
表1 20個(gè)字長(zhǎng)的數(shù)據(jù)塊1000萬(wàn)次測(cè)試結(jié)果(單位:毫秒)
表2 1000萬(wàn)個(gè)字長(zhǎng)的數(shù)據(jù)塊100次測(cè)試結(jié)果(單位:毫秒)
對(duì)20 個(gè)字長(zhǎng)的數(shù)據(jù)塊1000 萬(wàn)次測(cè)試結(jié)果,兩個(gè)系統(tǒng)平臺(tái)的結(jié)果基本一致,本文設(shè)計(jì)的哈希算法比BKDR 哈希算法的性能高8%左右對(duì)1000 萬(wàn)個(gè)字長(zhǎng)的數(shù)據(jù)塊測(cè)試中,WIN10平臺(tái)上的速度比WIN7平臺(tái)慢,而WIN7 平臺(tái)上,本文算法的性能優(yōu)勢(shì)達(dá)到了10.5%左右。
⑵哈希效果測(cè)試
哈希效果測(cè)試主要測(cè)試哈希沖突情況,沖突次數(shù)少的為優(yōu)。設(shè)計(jì)了兩類測(cè)試:第一類是直接測(cè)試,測(cè)試哈希碼沖突情況;第二類是映射測(cè)試,將哈希碼映射到一個(gè)數(shù)組上,看映射沖突情況。
測(cè)試字符串的字符表由71個(gè)字符組成,71個(gè)字符如下:
第一步,定長(zhǎng)字符串測(cè)試。使用上述71 個(gè)字符,生成了26003571 個(gè)字符串,字符串長(zhǎng)度為1、2、3、4、5的字符串個(gè)數(shù)分別為71、71×71=5041、71 ^3=357911、71^4=25411681、228867 個(gè)。用本論文哈希算法和BKDR 哈希算法計(jì)算這些字符串的哈希碼,均沒(méi)有沖突。
第二步,隨機(jī)字符串及映射沖突測(cè)試。使用上述71 個(gè)字符隨機(jī)生成長(zhǎng)度為1-50 的字符串240000 個(gè),分別用本文哈希算法和BKDR 哈希算法計(jì)算哈希碼,并映射到尺寸為300000的數(shù)組上,檢驗(yàn)哈希碼沖突和映射沖突情況。12 次測(cè)試結(jié)果如表3 所示,本算法哈希碼沖突高一些,映射沖突相當(dāng)略高。
表3 隨機(jī)字符串及映射沖突測(cè)試對(duì)比(單位:次)
基本型的隨機(jī)字符串的沖突測(cè)試中,哈希沖突效果稍差。原因是每輪計(jì)算過(guò)程中的左移操作,損失了中間結(jié)果的高7 位,并且字符高位都是0,無(wú)法充分對(duì)數(shù)據(jù)位進(jìn)行混淆和擴(kuò)散。
改進(jìn)型再加一次中間哈希碼,增加了一個(gè)加法操作,可以在對(duì)性能影響不大的情況下,提升數(shù)據(jù)位的混淆和擴(kuò)散效果。隨機(jī)生成240000 個(gè)字符串映射到300000 個(gè)數(shù)組元素的部分測(cè)試結(jié)果如表4 所示,改進(jìn)型算法哈希效果與BKDR算法相當(dāng)。
表4 改進(jìn)算法隨機(jī)字符串沖突測(cè)試對(duì)比(單位:次)
本文還測(cè)試了隨機(jī)生成3000、8000、16000、24000個(gè)字符串映射到5000、10000、20000、30000 個(gè)數(shù)組元素,兩個(gè)算法效果也是相當(dāng)。
改進(jìn)后的算法,因?yàn)槎嗔艘淮渭臃ú僮?,性能上?huì)略慢。分別在上述WIN7 和WIN10 平臺(tái)上測(cè)試,WIN7 平臺(tái)性能比BKDR 算法快8%左右。在WIN10平臺(tái)兩個(gè)算法性能持,結(jié)合上面的性能測(cè)試,推測(cè)是在新的平臺(tái)中,乘法指令得到了優(yōu)化,使乘法運(yùn)算性能得到了提高。
本文針對(duì)字符串哈希計(jì)算需求,提出了一種快速哈希算法,本算法結(jié)構(gòu)簡(jiǎn)單、易實(shí)現(xiàn)。在性能上優(yōu)于BKDR 哈希算法,在哈希效果上與BKDR 算法相當(dāng)。尤其是針對(duì)長(zhǎng)度為5 及以下的字符串的哈希計(jì)算,使用本文基本型算法計(jì)算的哈希碼抗沖突效果與BKDR算法相當(dāng),在性能上有顯著優(yōu)勢(shì)。
在對(duì)乘除法沒(méi)有顯著優(yōu)化的平臺(tái)上,比如嵌入式平臺(tái)和系統(tǒng)、單片機(jī)開發(fā)中,本算法與BKDR 相比,具有明顯的性能優(yōu)勢(shì),在對(duì)計(jì)算功耗和性能比較敏感的應(yīng)用場(chǎng)合,使用本算法能節(jié)省8%-11%左右的算力消耗。
本算法的提出,為快速字符串哈希算法,提供了一種新的實(shí)用方法。