1. 程式人生 > >Hash演算法(含python實現)

Hash演算法(含python實現)

1. 簡介

雜湊(hash)也翻譯作雜湊。Hash演算法,是將一個不定長的輸入,通過雜湊函式變換成一個定長的輸出,即雜湊值。

這種雜湊變換是一種單向運算,具有不可逆性即不能根據雜湊值還原出輸入資訊,因此嚴格意義上講Hash演算法是一種訊息摘要演算法,不是一種加密演算法。常見的hash演算法有:SM3、MD5、SHA-1等 。

2. 應用

Hash主要應用在資料結構以及密碼學領域。

在不同的應用場景下,hash函式的選擇也會有所側重。比如在管理資料結構時,主要要考慮運算的快速性,並且要保證hash均勻分佈;而應用在密碼學中就要優先考慮抗碰撞性,避免出現兩段不同明文hash值相同的情況發生。

2.1 在密碼學領域的應用

在密碼學中,Hash演算法的作用主要是用於訊息摘要和簽名,換句話說,它主要用於對整個訊息的完整性進行校驗。比如一些登陸網站並不會直接明文儲存使用者密碼,儲存的是經過hash處理的密碼的摘要(hash值),當用戶登入時只需要對比輸入明文的摘要與資料庫儲存的摘要是否相同;即使黑客入侵或者維護人員訪問資料庫也無法獲取使用者的密碼明文,大大提高了安全性。

2.2 在資料結構中的應用

使用Hash演算法的資料結構叫做雜湊表,也叫散列表,主要是為了提高查詢的效率。它通過把關鍵碼值對映到表中一個位置來訪問記錄,以加快查詢的速度。這個對映函式就是hash函式,存放記錄的陣列叫做雜湊表。在資料結構中應用時,有時需要較高的運算速度而弱化考慮抗碰撞性,可以使用自己構建的雜湊函式。

3. Hash演算法的python實現

3.1 自定義雜湊函式

自定義雜湊函式通常可利用除留餘數、移位、迴圈雜湊、平方取中等方法。下面這個例子就是我自己定義的一個雜湊函式,運用了取模運算和異或運算。

# coding:utf-8
# 自定義雜湊函式

def my_hash(x):
    return (x % 7) ^ 2

print(my_hash(1)) # 輸出結果:3
print(my_hash(2)) # 輸出結果:0
print(my_hash(3)) # 輸出結果:1
print(my_hash(4)) # 輸出結果:6

3.2 hash()函式

在python中有內建的雜湊函式hash(),返回一個物件(數字、字串,不能直接用於 list、set、dictionary)的雜湊值。示例程式碼如下:

# coding:utf-8
# hash()

print(hash(1))
print(hash(1.0))    # 相同的數值,不同型別,雜湊值是一樣的
print(hash("abc"))
print(hash("hello world"))

在執行時發現了一個現象:相同字串在同一次執行時的雜湊值是相同的,但是不同次執行的雜湊值不同。這是由於Python的字串hash演算法有一個啟動時隨機生成secret prefix/suffix的機制,存在隨機化現象:對同一個字串輸入,不同直譯器程序得到的hash結果可能不同。因此當需要做可重現可跨程序保持一致性的hash,需要用到hashlib模組。

3.3 hashlib模組

hashlib提供了常見的摘要演算法,如MD5,SHA1等等。示例程式碼如下:

# coding:utf-8
# 使用hashlib模組
import hashlib

md5 = hashlib.md5()     # 應用MD5演算法
data = "hello world"
md5.update(data.encode('utf-8'))
print(md5.hexdigest())