Python 3 中的确定性哈希

Deterministic hashing in Python 3

我通过以下方式使用字符串散列来播种随机状态:

context = "string"
seed = hash(context) % 4294967295 # This is necessary to keep the hash within allowed seed values
np.random.seed(seed)

不幸的是(对于我的使用而言)这在 Python 3.3 及更高版本中的运行之间是不确定的。我知道我可以将 PYTHONHASHSEED 环境变量设置为一个整数值以重新获得确定性,但我可能更喜欢感觉不那么骇人听闻的东西,并且不会完全忽视随机散列增加的额外安全性.建议?

使用专门构建的哈希函数。 zlib.adler32() is an excellent choice; alternatively, check out the hashlib 模块以获得更多选项。

强制 Python 的内置 hash 是确定性的 本质上是 hacky。如果您想避免 hackitude,请使用不同的哈希函数——参见 Python-2 中的示例:https://docs.python.org/2/library/hashlib.html, 在 Python-3 中:https://docs.python.org/3/library/hashlib.html

你实际上可以 use a string as seed for random.Random:

>>> import random
>>> r = random.Random('string'); [r.randrange(10) for _ in range(20)]
[0, 6, 3, 6, 4, 4, 6, 9, 9, 9, 9, 9, 5, 7, 5, 3, 0, 4, 8, 1]
>>> r = random.Random('string'); [r.randrange(10) for _ in range(20)]
[0, 6, 3, 6, 4, 4, 6, 9, 9, 9, 9, 9, 5, 7, 5, 3, 0, 4, 8, 1]
>>> r = random.Random('string'); [r.randrange(10) for _ in range(20)]
[0, 6, 3, 6, 4, 4, 6, 9, 9, 9, 9, 9, 5, 7, 5, 3, 0, 4, 8, 1]
>>> r = random.Random('another_string'); [r.randrange(10) for _ in range(20)]
[8, 7, 1, 8, 3, 8, 6, 1, 6, 5, 5, 3, 3, 6, 6, 3, 8, 5, 8, 4]
>>> r = random.Random('another_string'); [r.randrange(10) for _ in range(20)]
[8, 7, 1, 8, 3, 8, 6, 1, 6, 5, 5, 3, 3, 6, 6, 3, 8, 5, 8, 4]
>>> r = random.Random('another_string'); [r.randrange(10) for _ in range(20)]
[8, 7, 1, 8, 3, 8, 6, 1, 6, 5, 5, 3, 3, 6, 6, 3, 8, 5, 8, 4]

可以很方便,例如使用输入文件的基本名称作为种子。对于相同的输入文件,生成的数字将始终相同。