More Computer Random vs. True Random
A little while ago in #haskell on Freenode, one topic of discussion was random number generators. I wasn’t at my computer at the time, but when I came back, dejones had linked to a blog post about the patterns of pseudo random number generators. The author had made a PHP script which generates a random image using PHP’s rand function and compares it to one generated with true random numbers. The difference is significant.
dejones complained that there was no image for /dev/random on Linux, and I was curious about Haskell’s built-in random number generator, so I wrote a Haskell program to do the same thing and ran it on Linux. (As I type this, I am still gathering entropy for the /dev/random run. Just a warning, it’s still not done. I will be updating this some time tomorrow with the final image.)
Update: I never did gather enough entropy. I allowed the computer to run over 24 hours while I did all kinds of perverse things to the hard drive (old one, wouldn’t be devastating to lose it anyway), and still couldn’t gather enough entropy to generate the image. Perhaps I would fare better if I altered the program to use every single bit from /dev/random instead of just using modulo two of each character.
My original program tested Haskell’s random number generator. It looks like this:
module Main where
import Control.Monad
import qualified Graphics.GD as GD
import System.Random
imageSize = (512, 512)
imagePoints = do x <- [0..(fst imageSize - 1)]
y <- [0..(snd imageSize - 1)]
return (x, y)
main = do image <- GD.newImage imageSize
plots <- randoms `liftM` getStdGen
sequence_ $ zipWith (plot image) imagePoints plots
GD.savePngFile "out.png" image
where plot i p True = GD.setPixel p (GD.rgb 255 255 255) i
plot i p False = GD.setPixel p (GD.rgb 0 0 0) i
I’m using the GD library to create a PNG image. I won’t bother explaining the code for this.
And here is what that creates:
So not too bad. Now let’s try Linux’s /dev/urandom:
module Main where
import Control.Monad
import qualified Graphics.GD as GD
import System.IO
imageSize = (512, 512)
imagePoints = do x <- [0..(fst imageSize - 1)]
y <- [0..(snd imageSize - 1)]
return (x, y)
main = do image <- GD.newImage imageSize
devfile <- openFile "/dev/urandom" ReadMode
hSetBuffering devfile NoBuffering
plots <- fmap ((==0) . (`mod` 2) . fromEnum) `liftM` hGetContents devfile
sequence_ $ zipWith (plot image) imagePoints plots
GD.savePngFile "out.png" image
where plot i p True = GD.setPixel p (GD.rgb 255 255 255) i
plot i p False = GD.setPixel p (GD.rgb 0 0 0) i
And here is what it looks like:
This looks pretty similar to the output of Haskell’s generator, to me, but if somebody sees something I don’t then please do tell.
The code for /dev/random is exactly like the code for /dev/urandom, except we, obviously, use /dev/random instead! I would post the output image here now, but I can’t seem to gather enough entropy yet. I have to go home now. I’ll just post the image some time tomorrow. Sorry about that!
Update: As I mentioned in the update above, I never did get this done. I will get around to it eventually.

