如何真正洗牌一副牌

caw*_*caw 12 java random android shuffle playing-cards

当我需要在Java/Android中随机播放一副扑克牌时,我Collections.shuffle(List<?> list)当然会使用它.我一直这样做,结果似乎可以接受.但他们不是.

本文所述,有52个!52张牌扑克牌可能独一无二的洗牌.这相当于约2 ^ 226.

但是,Collections.shuffle(List<?> list)使用new Random()默认它采用了48位的种子,因此只能创建2 ^ 48独特的洗牌-这仅是3.49*10^(-52)所有可能的洗牌%的!

那么如何以正确的方式洗牌呢?

我已经开始使用了SecureRandom,但最后还够吗?

List<Card> cards = new ArrayList<Card>();
...
SecureRandom secureRandom;
try {
    secureRandom = SecureRandom.getInstance("SHA1PRNG");
}
catch (NoSuchAlgorithmException e) {
    secureRandom = new SecureRandom();
}
secureRandom.nextBytes(new byte[20]); // force SecureRandom to seed itself
Collections.shuffle(cards, secureRandom);
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 4

您可能只能从特定的起始排列中获得 2 48 种不同的手牌,但并不要求您每次都以相同的排列开始。

据推测,一副牌完成后(扑克牌、二十一点等),它将处于不确定的顺序,并且这些重新排列中的任何一种都是合适的。

而且,如果您担心每次启动程序时都从固定的安排开始,只需在退出时保留该顺序并下次重新加载即可。

无论如何,2 48仍然是一个巨大的可能性(大约 280,000,000,000,000),对于纸牌游戏来说绰绰有余,当你意识到它限制的是洗牌而不是排列时更是如此。除非您是一位严肃的统计学家或密码学家,否则您所拥有的应该没问题。