Is java.util.Random really that random? How can I generate 52! (factorial) possible sequences?

前端 未结 9 1968
-上瘾入骨i
-上瘾入骨i 2020-12-22 15:56

I\'ve been using Random (java.util.Random) to shuffle a deck of 52 cards. There are 52! (8.0658175e+67) possibilities. Yet, I\'ve found out that the seed for

9条回答
  •  再見小時候
    2020-12-22 16:27

    Short solution which is essentially the same of dasblinkenlight:

    // Java 7
    SecureRandom random = new SecureRandom();
    // Java 8
    SecureRandom random = SecureRandom.getInstanceStrong();
    
    Collections.shuffle(deck, random);
    

    You don't need to worry about the internal state. Long explanation why:

    When you create a SecureRandom instance this way, it accesses an OS specific true random number generator. This is either an entropy pool where values are accessed which contain random bits (e.g. for a nanosecond timer the nanosecond precision is essentially random) or an internal hardware number generator.

    This input (!) which may still contain spurious traces are fed into a cryptographically strong hash which removes those traces. That is the reason those CSPRNGs are used, not for creating those numbers themselves! The SecureRandom has a counter which traces how many bits were used (getBytes(), getLong() etc.) and refills the SecureRandom with entropy bits when necessary.

    In short: Simply forget objections and use SecureRandom as true random number generator.

提交回复
热议问题