Use the built-in java.util.Random. Item 47 of Effective Java (second edition, page 215) brings this up as an example of why you should prefer the standard libraries over rolling your own. It begins by explaining that Math.abs(rnd.nextInt() % n
is a bad approach, since it doesn't yield a truly random distribution and that you should simply use rnd.nextInt(n)
instead. It goes on to say:
To write a version of the random
method that corrects these three
flays, you'd have to know a fair
amount about pseudorandom number
generators, number theory, and two's
complement arithmetic.
...
You don't have to concern yourself with the details of how nextInt(int)
does it job. A senior engineer with a background in algorithms spent a good deal of time designing, implementing, and testing this method and then showed it to several experts in the field to make sure it was right. Then the library was beta tested, released, and used extensively by millions of programmers for the better part of a decade. No flaws have yet been found in the method, but if a flaw were to be discovered, it would be fixed in the next relase. By using a standard library, you take advantage of the knowledge of the experts who wrote it and the experience of those who used it before you.
It should be noted that even though the example doesn't use exactly the same code as the one you're suggesting, it's even more true for your example. Taking the remainder of a random integer skews the distribution, but at least it has some appearence of randomness. Just moding the time is an even worse approach.
You underestimate the complexity of pseudo random number generators. The problem with the approach that you're suggesting is that not only is it possible that the distribution is far from random, but moreover, it will be really predictable. There are realworld examples of hackers exploiting pseudorandom number generators with predictable seeds to cheat at poker. Building secure software (Viega and McGraw, 2002) contains a full chapter discussing these issues.
Here's a good example of how poor PRNGs can be broken in practice. In 1999, the Software Security Group at Cigital discovered a serious flaw in the implementation of Texas Hold 'em Poker, which is distributed by ASF Software, Inc. The exploit allowed a cheating player to calculated the exact deck being used for each hand in real time. This means that a player using the exploit knows the cards in every opponent's hand as well as the cards that make up the flop (cards placed face up on the table after rounds of betting). A cheater can "know when to hold 'em and know when to fold 'em" every time. A malicious attacker could use the exploit to bilk innocent players of actual money without every being caught. (Page 238)
Here's two questions that discusses the complexity of randomness:
This is a paper that's only a few weeks old (but with a really lame title) describing how you could attack the session generation algorithm of PHP by utilizing the predictable seed of the PRNG: