考虑到set是一个无序的数据结构这一事实,我开始怀疑是否有可能使用它(或使用字典)创建一个真正的“随机”数字。
让我们考虑一个表示为字符串的输入数字:
input = "0123456789"
然后我们将字符串转换为集合:
input_set = set(input)
多次打印此操作的结果后,我们有以下示例输出:
{'9','3','4','6','0','7','1','8','5','2'}
{'3','4','2','1','5','7','0','8','6','9'}
现在我们可以将集合的元素转换为使用以下字符串的字符串:
output = ''.join(set_input)
上述集合的操作结果为:
9346071852
3421570869
以下列方式生成随机数是否会被认为是一种好习惯?
最重要的是,我是否正确理解它是一个“伪随机”数字,因为我们可以通过使用某些种子值或密钥来重现结果?
答案 0 :(得分:3)
不,这不是好习惯。
顺序由随机散列种子确定,并且此种子对于当前的Python解释器是固定的。您无法为每个翻译生成多个“随机”订单。散列种子也是实现细节,用于防止一类拒绝服务攻击。不同的Python实现(包括Python.org生成的未来版本)可以自由地提出不使用散列种子的集合的不同实现。有关详细信息,请参阅-R
switch documentation。
种子还旨在产生良好的散列性能,而不是加密安全性。集合中值的排序也由元素的插入顺序决定;它是将哈希值转换为确定元素排序的哈希表中可用的槽的(有限的)选择时每个值的哈希值和任何冲突的组合。如果你要重复你的实验,你几乎肯定会看到某些位置出现某些数字的偏见。
坚持secrets
module以生成加密安全随机数。
对于非安全操作,只需使用random
模块;从统计学角度来说,使用random.shuffle()
数字已经可以更好地分配数字。