微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在python中使用随机散列函数?

如何解决如何在python中使用随机散列函数?

我正在尝试实现一种称为潮汐标记随机算法。它在 these lecture notes 的第 2 单元中描述。为此,我需要一个随机选择的哈希函数,将整数 [1,...,n] 映射到 [1,n]。 Python 在库中有一些不同的哈希函数,但我没有找到一个可以让我指定域和范围并随机选择合适函数函数

这种东西存在吗?

解决方法

好吧,在我的脑海里,我会搭载 Python 的 hash() 但使用随机数扭曲它返回的数字。 (Note that hash() doesn't have a deterministic value between Python interpreter restarts either.)

import secrets

def gen_random_hasher(max_val=1024):
    seed = secrets.randbits(64)
    return lambda val: (hash(val) ^ seed) % max_val

s1 = gen_random_hasher()
s2 = gen_random_hasher()

print(s1('aaa'),s1(123))
assert s1('aaa') == s1('aaa')  # "prove" the function is deterministic
print(s2('aaa'),s2(123))

这会打印出例如

447 885
55 765

所以你可以分辨出 s1s2 是不同的。

,

您正在寻找的是 universal hash function。 许多哈希算法在内部使用随机数,可用于将它们泛化为通用哈希函数。

您也可以使用任何 integer hash function,然后在减少模数之前乘以一个大于 0 的随机整数。

根据散列前值的分布情况以及散列值需要分布的情况,这可能完全足够了:

from functools import partial
from random import randint

def hash_family(value,n,salt):             # output is [0,n) (i.e. excluding n)
  value=value*(2*salt+1)                   # multiplying with 0 is bad
  value=value^(value>>(n.bit_length()//2)) # xorshift to improve distribution
  value=value&((1<<n.bit_length())-1)      # cut off high bits for speed
  value=value*(2*salt+1)                   # another multiplication
  value=value^(value>>(n.bit_length()//2)) # another xorshift
  value=value&((1<<n.bit_length())-1)      # cut off high bits
  value=value%n                            # modulus reduction
  return value

random_hash = partial(hash_family,salt=randint(0,2**64))
>>> hash_family(23,100,56)
73
>>> hash_family(23,57)
52
>>> hash_family(23,58)
30
>>> random_hash(17,100)
42

对于加密强度,使用 python hashlib,那里的许多散列函数都有一个 salt 参数,可以使用 randint 设置并使用 partial 绑定以将其用作通用散列函数。范围缩小可以通过模运算来完成。

,

使用标准的md5 hash,使用os.urandom作为随机种子,通过seed可以复用hash函数

def get_random_hashfunc(_max=1024,seed=None):
    seed = seed or os.urandom(10)
    seed_hash_func = hashlib.md5(seed)
    def hashfunc(n):
        func = seed_hash_func.copy()
        func.update(n.to_bytes(n.bit_length(),'big'))
        return int.from_bytes(func.digest(),'big') % _max
    return hashfunc,seed

hash_func1,seed1 = get_random_hashfunc()
hash_func2,seed2 = get_random_hashfunc()
hash_func3,seed3 = get_random_hashfunc(seed=seed1)

>>> hash_func1(123)
156
>>> hash_func2(123)
931
>>> hash_func3(123)
156

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。