0

我需要生成 k 个哈希值(0 .. m-1),并且 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 操作?

4

3 回答 3

0

关于“k”和“m”是什么,您的问题尚不清楚。但是任何合理的散列函数输出的所有位都是同样“随机的”。因此,您可以将其切碎并单独使用。

于 2013-05-30T06:35:44.317 回答
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
于 2013-05-30T15:28:49.930 回答
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]
于 2013-08-12T23:54:26.557 回答