当随机不够随机--洗牌算法易犯的错误

来源:互联网 发布:外网访问内网mac服务器 编辑:程序博客网 时间:2024/05/08 23:27
错误1: 差一错误
试图遍历所有牌,将每一张牌跟另外一张随机选择的牌进行交换。函数random(n)返回一个0到n-1之间的随机数,而不是程序员所想的1到n之间的。因此,这个算法中第52张牌永远不会和他自己进行交换,也就是说第52张牌永远不会停在第52个位置。这是随机洗牌不够随机的第一个原因。

错误2:洗牌不均匀
将第i张牌和另外一张从整副也就是52张牌中随机选择的牌进行交换。而合适的洗牌算法应该只和第i到第n张牌中的一张进行交换。这是因为考虑到每一张牌应该只进行一次随机交换。一副牌有n!种不同的排列,合适的洗牌算法应该只产生每种排列一次。原算法使一些排列出现的概率明显高于另一些排列,是个不好的实现。

错误3:32位种子
如果你的业务或技术依赖于随机数的使用,最好的选择是采用一个硬件随机数产生器,而不是用一个带有伪随机数产生器的确定机,使用32位的种子。由于种子100%的决定了伪随机数产生器的输出,只有N^32种可能的种子值就意味着只有N^32种可能的打乱顺序。所以在理论上有8.0658×10^67种打乱顺序的情况下,他只有4百万可能。

错误4:系统时钟作为种子
使用Pascal函数Randomize()生成随机数,而这个函数是根据从午夜开始的毫秒数来选择种子的。由于一天之中只有86,400,000毫秒,也就意味着上述算法只能产生86,400,000种可能的乱序。但更糟糕的是,由于随机数产生器的种子是基于服务器时钟的,黑客们只要将他们的程序与服务器时钟同步就能够将可能出现的乱序减少到只有200,000种。到那个时候一旦黑客知道5张牌,他就可以实时的对200,000种可能的乱序进行快速搜索,找到游戏中的那种。所以一旦黑客知道手中的两张牌和3张公用牌,就可以猜出转牌和河牌时会来什么牌,以及其他玩家的牌。
0 0
原创粉丝点击