Python 3中的确定性散列

Jim*_*y C 5 python hash python-3.x

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

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

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

dus*_*uff 8

使用专用的哈希函数.zlib.adler32()是一个很好的选择; 或者,查看hashlib模块以获取更多选项.

  • 小心!我发现了困难的方法,但 adler32 的目的不是为了散列,而是为了纠错。其碰撞概率相当高。调试起来相当头疼。 (11认同)

Ale*_*lli 6

强制 Python 的内置函数hash具有确定性本质上很麻烦的。如果你想避免 hackitude,请使用不同的哈希函数 - 请参阅 Python-2 中的示例:https: //docs.python.org/2/library/hashlib.html和 Python-3 中的:https://docs .python.org/3/library/hashlib.html

  • 哈希值不应该是确定性的吗? (4认同)
  • hash() 仅在整个相同的运行中具有确定性,您不能保证它会在不同的运行中返回相同的哈希值。因此,这不利于磁盘上的持久性。 (4认同)

Eri*_*nil 5

您实际上可以使用字符串作为种子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]
Run Code Online (Sandbox Code Playgroud)

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