python - 在 Python 中生成非重复随机数

标签 python random numbers

好的,这是一个比听起来更棘手的问题,所以我转向堆栈溢出,因为我想不出一个好的答案。这就是我想要的:我需要 Python 以随机顺序生成一个从 0 到 1,000,000,000 的简单数字列表,用于序列号(使用随机数,这样您就无法知道分配了多少或进行计时攻击一样容易,即猜测下一个会出现)。这些数字与链接到它们的信息一起存储在数据库表(索引)中。生成它们的程序不会永远运行,因此它不能依赖内部状态。

没什么大不了的吧?只需生成一个数字列表,将它们插入一个数组并使用 Python “random.shuffle(big_number_array)”,我们就完成了。问题是我想避免存储数字列表(因此读取文件,从顶部弹出一个,保存文件并关闭它)。我宁愿动态生成它们。问题是我能想到的解决方案有问题:

1) 生成一个随机数,然后检查它是否已经被使用过。如果它已被使用生成一个新号码,请检查,根据需要重复,直到找到一个未使用的号码。这里的问题是我可能会不走运并在获得未使用的数字之前生成大量使用过的数字。可能的解决方法:使用一个非常大的数字池来减少这种情况的可能性(但我最终会得到愚蠢的长数字)。

2) 生成一个随机数,然后检查它是否已经被使用过。如果它已被使用,从数字中加减一并再次检查,继续重复,直到我找到一个未使用的数字。问题是这不再是一个随机数,因为我已经引入了偏差(最终我会得到一串数字,你就可以预测下一个数字,成功率更高)。

3) 生成一个随机数,然后检查它是否已经被使用过。如果它已被用于添加或减去另一个随机生成的随机数并再次检查,问题是我们回到了简单地生成随机数并像解决方案 1 中一样检查。

4) 吸收并生成随机列表并保存它,让守护程序将它们放入队列中,以便有可用的数字(并避免不断打开和关闭文件,而是将其批处理)。

5) 生成更大的随机数并对它们进行散列(即使用 MD5)以获得更小的数值,我们应该很少会发生冲突,但我最终会再次得到大于需要的数字。

6) 将基于时间的信息添加或附加到随机数(即 unix 时间戳)以减少冲突的机会,我再次得到比我需要的更大的数字。

任何人都有任何聪明的想法可以减少“冲突”的机会(即生成一个已经被采用的随机数),但也可以让我保持数字“小”(即小于十亿(或为您的欧洲人提供一亿 =))。

答案以及我接受它的原因:

所以我将简单地选择 1,并希望这不是问题,但如果是,我将采用生成所有数字并存储它们的确定性解决方案,以便保证获得一个新的随机数,我可以使用“小”数字(即 9 位数字而不是 MD5/等)。

最佳答案

这是一个巧妙的问题,我已经考虑了一段时间(解决方案类似于 Sjoerd's ),但最后,这是我的想法:

使用你的观点 1) 并停止担心。

假设真正的随机性,之前已经选择随机数的概率是之前选择的数字的计数除以池的大小,即最大数字。

如果您说您只需要 10 亿个数字,即 9 位数字:请多给自己 3 位数字,这样您就有 12 位数字序列号(即三组四位数字 - 美观且易读)。

即使您之前已经选择了十亿个号码,您的新号码已经被选中的概率仍然只有 0.1%。

执行第 1 步并再次绘制。您仍然可以检查“无限”循环,例如不要尝试超过 1000 次左右,然后回退到添加 1(或其他内容)。

您将在该备用方案被使用之前中奖。

关于python - 在 Python 中生成非重复随机数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2076838/

相关文章:

python - 为什么 Eventhub 异步接收器每分钟仅获取 30-35 条消息?

Python:最后的While循环不断生成新的随机卡,如何让它生成一次并停止?

java - 如何创建包含多个单个字母的随机长度字符串?

Python - 将字符串拆分为参数

python - Maya Python 创建和使用压缩包?

python - self.direction = pygame.Vector2(1, 0)#Vector2(1,0) ;属性错误: 'module' object has no attribute 'Vector2'

python - 如何更新 django DeleteView 中的关联模型

javascript - 随机化 li 项并卡住多个

MYSQL:序号表

java - 如何生成具有特定范围的唯一随机数