2014年8月17日 星期日

[python] Hash演算法效能測試

因為使用過許多Hash經驗

從一開始可以用就MD5

考慮到效能時開始改用mmh3 / CRC

到現在顧慮到碰撞安全思考 SHA

在這當下突然想了解每個演算法計算速度的差異


便開始以下實驗

測試項目:

1. MD5       (python 內建)
2. mmh3     (mmh3 官網)
3. SHA       (Crypto 套件)
4. SHA512 (Crypto 套件)
5. CRC       (zlib)

測試方法/結果:

1. timeit.timeit(stmt='h=md5.md5("Hello");h.hexdigest();', setup='import md5', number=100000)
0.112001895905

2. timeit.timeit(stmt='mmh3.hash("Hello")', setup='import mmh3', number=100000)
0.0195569992065

3. timeit.timeit(stmt='h=SHA.new();h.update("Hello");h.hexdigest();', setup='from Crypto.Hash import SHA', number=100000)
0.644107103348

4. timeit.timeit(stmt='h=SHA512.new();h.update("Hello");h.hexdigest();', setup='from Crypto.Hash import SHA512', number=100000)
0.711499929428

5. timeit.timeit(stmt='zlib.crc32("Hello")', setup='import zlib', number=100000)
0.0303909778595

結論:

SHA512 執行時間 = SHA + MD5
SHA 執行時間 = MD5 * 6
MD5 執行時間 = CRC * 3.7
CRC 執行時間 = mmh3 * 1.6

大多情況都不出我所料

除了CRC和mmh3的效能!! Holy S**t!

我以為CRC沒算什麼東西想說效能快打算用來作為即時驗證

沒想到mmh3更勝一籌,果然是目前最快算法

計算速度排名如下:

1. mmh3
2. CRC
3. MD5
4. SHA

還好我以前為了效率都還是用mmh3

只是近日想用C來改寫成自己版本就肖想用CRC來處理

看過演算法後自認碰撞安全排名如下

1. SHA
2. MD5
3. mmh3
4. CRC

因為mmh3的結果非固定長度而CRC相反所以自認定碰撞程度CRC肯定較高

另外MD5真的很可憐,論效率和安全都不及左右

因為許多程式內都預設MD5

就是方便很適合新手

阿母勾近幾年被撞到後...還是很多人用啦 XDDD


對我來說如果只考慮安全應該還是用SHA512

SHA512和SHA效能只差0.1其實也沒快到哪去 (疑? 明明就可以再塞個DM5)

CRC就吃飽洗洗睡吧...

是說想作為資料驗證夠快用CRC

沒想到mmh3 很威的還是你把你超車了 (雖然差一點點而已)

補充:

最近發現python內建的base64也有內建CRC計算

在好奇心趨使下發現

timeit(stmt='bs.binascii.crc32("Hello")', setup='import base64 as bs', number=100000)
0.03987398338317871

比起zlib還要慢上0.01秒

恩...網路上流傳最快CRC至少不是騙人的

但還是無法動搖mmh3的地位

2 則留言:

  1. 如果hash random字串不知道有沒有差
    搞不好有偷偷做cache?

    回覆刪除
    回覆
    1. 我用os.urandom(5) 產生隨機5字元作為替換
      計算結果為mmh3 < crc < md5 < SHA512 < SHA
      在這次計算中差距變小了 (應該是隨機產生時間干擾)
      但基本上排名沒啥變化
      mmh3, crc, md5 之間的差異不是很大
      而SHA計算時間是mmh3的兩倍

      另外SHA512無論試幾次速度總是快SHA一點點
      不知道有沒有SHA專家可以解釋 XDDD

      刪除