Python 到底有多随机?
Posted
技术标签:
【中文标题】Python 到底有多随机?【英文标题】:Just how random is it possible for Python to be? 【发布时间】:2017-05-17 16:51:45 【问题描述】:如果您从一个包含数百甚至数千个单独项目的列表开始,并且您希望 Python(一次)随机选择一个(用于创建密文),那么它到底有多“随机”?由于应用程序的 crypt0graphic 特性,任何重复项(整数、字符串)都不能重复,这一点非常重要。但是有什么方法可以自信地从字典中进行随机选择吗?
感谢这样的建议,但这个问题不是列出的两种可能性的重复。一方面,可供选择的项目范围必须是完全动态的,但为了简洁起见,我限制了对应用程序机制的描述,它是为了教育/娱乐目的而不是为了拯救世界; -)
【问题讨论】:
如果你这样做random.shuffle(container)[:n]
其中n
是你想要的结果数,那可能会奏效。只是重复选择可能会导致重复
Pick N items at random from sequence of unknown length 的可能重复项。简短的回答:随机播放一次,然后弹出 N 次。
Generating random integers in a specific range的可能重复
如果您打算将其用于教育目的,那甚至比生产质量更重要。教人们做错事比自己做错事要糟糕得多。
【参考方案1】:
来自random 模块文档:
警告:此模块的伪随机生成器不应用于安全目的。如果您需要加密安全的伪随机数生成器,请使用
os.urandom()
或SystemRandom
。
【讨论】:
【参考方案2】:如果您使用的是 Python 3.6,则可以使用:
from secrets import choice
choice(your_options)
根据module documentation:
secrets
模块用于生成加密强随机数,适用于管理密码、帐户身份验证、安全令牌和相关机密等数据。
【讨论】:
这会给你一个来自your_options
的随机项目,而不是多个没有重复的项目。当然,避免重复可能是个坏主意,这完全取决于 OP 在做什么。在某些加密应用中,您确实不想要重复,例如在format-preserving encryption 中使用的类似随机播放的过程中
@PM2Ring 好点,很遗憾secrets
没有sample
函数。但它可以通过在 while
循环中使用某种 unique_everseen (1 2) 功能来实现。【参考方案3】:
首先,您所说的是人类感知生成器的随机性;不是随机的东西。 how Spotify shuffles music 上有一个很好的帖子,对人类来说似乎更随机,同时实际上减少了熵。 (或者至少他们过去是怎么做的)。
从未在同一条消息中两次使用相同的数字/字符串是比二战期间用于破解 Enigma 的漏洞更严重的安全漏洞。
其次,“随机性”可能是指“多少熵”。
第三,正如其他人指出的那样,Python 中的 random
模块在密码学上并不安全。不要将它用于与密码学相关的代码。有os.urandom()
、SystemRandom
或secrets
,但您可能不应该使用它们中的任何一个,因为:
第四,也是最重要的一点,除非您拥有密码学学位,否则您不应该永远不要使用自己的加密货币。检查最先进的技术,并改用它。 Crypto SE 知道他们的东西,Security SE 也是如此。
【讨论】:
我认为您的第三点需要澄清一下。使用默认的 Mersenne Twister(或早期 Python 中使用但已在 Python 3 中删除的旧 Wichmann-Hill 生成器)进行加密当然不安全,但如果您指定SystemRandom
生成器。但当然,你的第四点胜过这一点。 :)
@PM2Ring 好点。我有一些感觉,提供默认不安全的随机功能的库/模块可能不会一直考虑安全性,比如不使用恒定时间比较。仅支持加密安全随机的库/模块/包/...(希望)一直是安全的。例如,Go 有 crypto/rand
和 rand
作为两个独立的包,Python 现在有 secrets
和 random
。
好点! random
中的函数当然不是旨在抵抗定时攻击,但这可能对于 OP 的应用程序来说不是问题。【参考方案4】:
最近发布的 Python 3.6 中的一大新增功能是添加了一个 secrets
模块,用于生成强加密随机数。
【讨论】:
以上是关于Python 到底有多随机?的主要内容,如果未能解决你的问题,请参考以下文章
python随机生成近100年内的200个人的生日,统计同一天出生的人数,并按照人数的多少从高到底排序?