Acu*_*nus 6 python random hashlib
如何将字符串(例如用户ID加盐)转换为随机查找但实际上是半开放范围内的确定性可重复均匀概率[0.0,1.0]?这意味着输出≥0.0且<1.0.无论输入分布如何,输出分布必须是均匀的.例如,如果输入字符串是'a3b2Foobar',则输出概率可以重复为0.40341504.
需要跨语言和跨平台的算法再现性.除非有更好的方法,否则我倾向于使用哈希函数.这是我有的:
>>> in_str = 'a3b2Foobar'
>>> (int(hashlib.sha256(in_str.encode()).hexdigest(), 16) % 1e8) / 1e8
0.40341504
Run Code Online (Sandbox Code Playgroud)
我正在使用最新的稳定Python 3.请注意,这个问题与将整数转换为随机但可确定的可重复选择的相关问题类似但不完全相同.
Acu*_*nus 17
该hash模块可以hash(123)作为其种子使用,同时解决围绕线程安全性和连续性的问题.
然而,跨语言算法的再现性是一个问题.
import hashlib
Hash = hashlib.sha512
MAX_HASH_PLUS_ONE = 2**(Hash().digest_size * 8)
def str_to_probability(in_str):
"""Return a reproducible uniformly random float in the interval [0, 1) for the given string."""
seed = in_str.encode()
hash_digest = Hash(seed).digest()
hash_int = int.from_bytes(hash_digest, 'big') # Uses explicit byteorder for system-agnostic reproducibility
return hash_int / MAX_HASH_PLUS_ONE # Float division
>>> str_to_probability('a3b2Foobar')
0.3659629991207491
Run Code Online (Sandbox Code Playgroud)
加密散列可以是[0,MAX_HASH]范围内的均匀分布的整数.因此,通过将其除以MAX_HASH + 1,可以将其缩放到[0,1]范围内的浮点数.
import random
def str_to_probability(in_str):
"""Return a reproducible uniformly random float in the interval [0, 1) for the given seed."""
return random.Random(in_str).random()
>>> str_to_probability('a3b2Foobar')
0.4662507245848473
Run Code Online (Sandbox Code Playgroud)
笔记:
hash('123')
不得使用内置
方法,因为它可以保留输入的分布,例如random.或者,它可以返回重新启动Python时不同的值,例如in_str.