2013-05-30 54 views
0

我需要生成k個散列值(0 .. m-1),並且k個數字應該是不同的。 根據不同的散列種子,散列值應該不同。使用python生成k個散列值

我發現了這個代碼,但是對於我來說只用一個值就太大了。

import hashlib, uuid 
password = "abc" <-- key 
salt = str(10) # <-- hash seed 
value = hashlib.sha1(password + salt).hexdigest() 
print value # 105dee46d56df0c97ca9b6a09e59fbf63d8ceae2 

如何獲得0和m-1之間的良好k散列值?或者是否可以將值分成k個部分來應用mod操作?

+0

你想使它具有可變'M'號工作?或者它是一個特定的m? –

+0

...你試圖產生一個哈希碰撞什麼的? – muhmuhten

+0

@JoranBeasley:它可以是兩個。 – prosseek

回答

0

我發現mmh3是迄今爲止最好的選擇。

import mmh3 

def getHash(key, m, k): 
    result = set() 
    seed = 1 
    while True: 
     if len(result) == k: 
      return list(result) 
     else: 
      b = mmh3.hash(key, seed) % m 
      result.add(b) 
      seed += 10 
      print result 

if __name__ == "__main__": 
    print getHash("Hello", 100, 5) 
    print getHash("Good Bye", 100, 5) 

結果:

set([12]) 
set([43, 12]) 
set([43, 12, 29]) 
set([88, 43, 12, 29]) 
set([88, 80, 43, 12, 29]) 
[88, 80, 43, 12, 29] 
set([20]) 
set([2, 20]) 
set([2, 20, 70]) 
set([2, 75, 20, 70]) 
set([2, 75, 20, 70, 39]) 
[2, 75, 20, 70, 39] 
0

關於「k」和「m」是什麼,你的問題還不清楚。但是任何合理的散列函數輸出的所有位都是「隨機的」。所以你可以把它切碎並分開使用。

0

這是工作的代碼。

import hashlib, uuid 
# http://stackoverflow.com/questions/209513/convert-hex-string-to-int-in-python 

def getHash(key, hashseed, m, k): 
    """ 
    We use sha256, and it generates 64 bytes of hash number, so k should be 2 <= k <= 32 
    However, because of duplicity the real limit should be much lower. 

    Todo: You can concatenate more sha256 values to get more k values 
    """ 
    salt = str(hashseed) 
    hashed_password = hashlib.sha256(key + salt).hexdigest() 
    if k > 32: raise Error("k should be less than 32") 
    if k <= 1: raise Error("k should be more than 2") 

    result = [] 
    index = 0 

    # make the non-overwrapping hash value below m 
    while True: 
     value = int(hashed_password[index:index+2], 16) % m 
     index += 2 

     # second loop for detecting the duplicate value 
     while True: 
      if value not in result: 
       result.append(value) 
       break 
      # Try the next value 
      value = int(hashed_password[index:index+2], 16) % m 
      index += 2 
     if len(result) == k: break 

    return result 

if __name__ == "__main__": 
    res = getHash("abc", 1, 10, 5) # seed:1, m = 10, k = 5 
    assert len(res) == 5