From what I’ve read, /dev/random on Linux boxes acts as a binary file that has environmentally random bits, taking noise from various devices like the network device, keyboard, or mouse. Is there any way to achieve a similar effect under Windows? Glancing over my MSDN help that came with VC++6.0, the only mouse capturing that can occur must have an active window. Clearly this isn’t the desired goal. I could find nothing about capturing any other input for a program that might run in the background. Even if my understanding of /dev/random is incorrect, my goal is similar: to create a file that serves as a bunch of random numbers, which could be used in random number generating routines other than calling srand(time(0)) or seeding an entire pseudo-random number generator.
I’ve tried looking around, but my searches pull up nothing of interest other than using boost libraries or having a computer with an internet connection getting a random seed from some website. These seem a little bit… er, ungeneralized.
Try the CryptGenRandom function from Win32’s CryptoAPI. It appears to work similarly to the dev/random device in Linux. From the MSDN docs on CryptGenRandom:
"CryptoAPI stores an intermediate random seed with every user. To form the seed for the random number generator, a calling application supplies bits it might have—for instance, mouse or keyboard timing input—that are then added to both the stored seed and various system data and user data such as the process ID and thread ID, the system clock, the system time, the system counter, memory status, free disk clusters, the hashed user environment block. This result is SHA-1 hashed, and the output is used to seed an RC4 stream, which is then used as the random stream and used to update the stored seed. "
Awesome. Thank you both very much. Egads and the CryptGenRandom are exactly what I was looking for. I know, I know, there are coding sites available, but I’ve searched them and all I get are references to boost libraries and random.org. This is much better.
Two issues that should be addressed:
[ul]
[li]Since you’re using Windows, I guess your program will be working in a desktop environment or in another world where frequent human interaction is the norm. If that’s the case, environmental noise is a fairly good source for entropy. A backroom server shouldn’t rely upon keypress timings for a source, for obvious reasons.[/li]
But know that the amount of time it takes to fill your entropy pool is going to be variable and could easily become a bottleneck unless the user is constantly doing something. Linux provides the special file /dev/urandom to address this issue: /dev/urandom always gives you as many bytes as you request, meaning it is hooked up to a subprogram in the kernel that algorithmically generates pseudo-random numbers. Frequently, this is good enough for non-cryptographic purposes. (I know Linux-specific knowledge is worthless to you. I’m giving an example of a possible solution to a possible problem.)
[li]If you decide that the wait between full entropy pools is unacceptable, choose a good PRNG. Which PRNG is good for you will be highly dependent upon what you need the bits for. For a simple card-shuffler in a game, a simple linear-congruential fed by the system clock could be good enough. It will certainly be fast. For modeling, the de facto standard has become the famous Mersenne twister. For cryptography, if you feel you must use pseudo-randomness at all, try Blum Blum Shub or Fortuna. [/li][/ul]
For more details, check my Wikipedia link and Google. For cryptography info, buy and devour the works of Bruce Schneier.
Thanks, Derleth. I didn’t mean to shy away from Linux specifically in a general sense. Some day (he says, looking at his spare computer) I intend to get Linux up and running, and in fact when I code I try to make it as ANSI specific as possible so whenever that day comes I have very little retooling to do. In fact, most of what I’d use a random number for doesn’t need anything more than rand, I just like to spread my wings.
erislover, it’s good to see people getting interested in randomness for its own sake. You could (should) get into some number theory and decide what kind of randomness you want. There’s a good program by John Walker (of www.fourmilab.ch, a good website) called ent. It will perform some standard tests on any data source (usually a file, but in the *nix world everything is a file) and tell you how random it is, by various metrics. He distributes the C source and precompiled binaries for MS-DOS/Windows.
As for testing out Linux, try Knoppix. It’s a full Linux distro that fits on a bootable CD-ROM, and it allows you to run the OS without installing anything on a hard drive. If you like it, I think there’s an option to partition the disk and install it in the traditional way, but the main point of Knoppix is to be a try-before-you-commit distro. Here’s the distro’s homepage.
(Other good newbie distros include Fedora (nee Red Hat) and Mandrake. Stay away from Debian and Slackware, as those are made by and for wizards.)