- By Matt Stephens
- November 21, 2006
At first glance, the linked article seems like a disturbing expose of the limitations of Java’s java.util.Random class. The problem (as claimed in the article): Random just ain’t that random.
The linked page showcases a visual test applet which demonstrates quite ably that the Random class is, in fact, merely pseudo-random (or perhaps more to the point, its random series loops round much sooner than it should). When in full flow, the applet’s checkered pattern reminds me of a spaced-out game of Frogger. Lines whiz to the left and to the right as if the poor frog is trying to cross the German Autobahn. If Random was truly random, you’d see “snow crash”-style random static instead.
The applet’s deterministic behavior basically illustrates that Random would be a completely inappropriate choice for cryptographically secure systems (or rather, for systems that need to be cryptographically secure); and as the article’s title suggests, Sun’s definition of randomness is completely broken.
(Pause for dramatic effect).
Except... java.util.Random isn’t a random number generator at all, it’s a pseudo-random number generator: and it’s supposed to work that way. So, despite the sensational title to the article ("Sun redefines randomness!"), they've basically got it right.
That said, there is a slight hiccup in the implementation. The problem (as described in the linked web page) is that the random number generator repeats itself every 10^N when it should have repeated a lot less often. But this is a fairly minor issue given the intended uses of this class.
Random’s “contract” states that, if you feed it the same seed, you’ll get the same series of “random-ish” numbers back. Developers sometimes use this feature for testing and debugging purposes. So if the behavior of java.util.Random was “fixed” (as the article’s author suggests), much code out there in Java-land would break.
It shouldn’t break, because relying on the internal behavior of a pseudo-random generator is a bad, bad thing. Even simply relying on a class called “Random” for predictable results seems like a bad idea. Just from a Responsibility-Driven Design (RDD) perspective, perhaps these developers should have created their own class called Determinable, that simply returns the same old stream of numbers every time.
Another issue with the linked-to applet is that it’s taking a flawed approach. It repeatedly plots the least significant bit (LSB) of the Random.nextLong() method once for each point in the grid. If the applet plotted the most significant bit (MSB) instead, you’d get something more like this applet. How about that, it’s random static!
But, unfortunately, the wrongness of the demo doesn’t change the fact that there is a lot of Java code out there that relies on the non-random behavior of Random – however misguided that reliance is. Luckily for the owners of this misguided code, backwards compatibility is something that Sun cares about rather a lot.
Perhaps they should gain inspiration for their randomization needs from the now-defunct Princeton Engineering Anomalies Research (PEAR) program.
Luckily, Sun has also provided us with a built-in solution. Developers who really want a cryptographically secure random number generator (or indeed, anyone who just wants a bit more randomness in their entropy pool) should use the much more robust SecureRandom class.