http://www.perlmonks.org?node_id=659633


in reply to Problem running code until a user hits a key

Even with Time::Hires's gettimeofday, that doesn't sound like a very effective way to randomly seed things as most users would be prone to hitting a key at a fairly predictable interval if they're just doing it to provide a random seed. (I would expect that the typical user would generally either do it as quickly as possible (consistent time based on user's reflex speed) or wait a fairly consistent N seconds (where N is user-dependent, but generally no greater than 5).)

I would expect to get greater randomness by using Perl's built-in rand to generate your seed value(s) instead. If rand's pseudo-randomness isn't truly random enough for you and you're running under Linux, reading from /dev/random or /dev/urandom will definitely give you much greater randomness than what you appear to be trying to do.

Replies are listed 'Best First'.
Re^2: Problem running code until a user hits a key
by davies (Prior) on Dec 30, 2007 at 17:17 UTC
    I'm not too concerned about getting huge numbers of iterations, just enough for the output to be unpredictable. I'm not sure if my original node made it clear that I'm intending to use multiple PRNGs, for a variety of reasons. I'm also not too worried about sucking up CPU time for the few seconds it will take the user to initialise however many PRNGs are chosen. I would worry about using rand, though, as this would mean that all the PRNGs were seeded in a possibly predictable sequence or set of sequences. I ran into a similar problem about 25-30 years ago, and it left its scars! :-)

    Trying ReadKey(-1) gets me about 100K iterations per second without the PRNGs in place, so the solutions that have been suggested here certainly work in that regard. I'm also interested in jaldhar's comments about needing to reset the terminal - it's something else I didn't pick up from the documentation I read. Actually, it looks as though I must have missed some docs altogether. Whoops.

    Thanks to all for all the help.

    Regards,

    John Davies
      Yep, I did catch that you're seeding multiple PRNGs. My criticism of the method is based on the notion that, since most users will let it run for about the same amount of time each time you do this 'press a key to seed next PRNG' process, you'll end up with a set of seeds which is more predictable than the output of rand. e.g., If the average user has a 0.1 second variance in their response times, then an attacker would only have a range of about 10,000 seeds (based on your "about 100K iterations per second") to check, with those near the middle of the range being much more likely to occur. Granted, each user may have a different range of likely response times, but many users would probably have similar enough ranges that the set of likely seeds would still be smaller than the set of possible results from a mere 16-bit PRNG.
        Even if the range is only 1,000 for each PRNG, things explode exponentially. What I'm actually trying to do is deal Bridge hands. There are 5.36E28 different hands that can be dealt, so even a 24 bit PRNG could cover only a tiny fraction, which may not be representative. My strategy is based loosely on the Enigma coding machine, but with a variation.

        The idea is that the user will first select the sequence of PRNGs that will be used. The sequence will not be of fixed length (unlike Enigma, which had a set number of wheels) and PRNGs can be repeated within the sequence (again unlike Enigma, where a wheel could be used only once in any day's setting). Let's say that the attacker knows that a sequence of five PRNGs will be used without repeats, because he knows the Tournament Director. Even at a range of 1,000, that's 1.2E17 different series of deals that might come up. Since he won't see the first board before he starts playing, he won't have much time to work out what the other boards are likely to be. Getting access to the boards before play would be far easier, but that's beyond the scope of this lecture :-).

        Thanks again for all the help,

        John Davies