Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I am generating a randam alpha-numeric string as part of a perl CGI module. I suspect the answer to this question is no. But is a string more random if it is generated from a random character array or a sorted array?

Replies are listed 'Best First'.
Re: String randomness
by djantzen (Priest) on Aug 16, 2002 at 01:11 UTC

    I'm not sure the question is really intelligible. Computers are inherently deterministic, which is why random number generators are needed to give the appearance of randomness for some applications. This means that a string generated "randomly" from a set of characters will be no more or less intrinsically random whether the characters within the set are ordered or not. A well written algorithm for generating random behavior should be convincing no matter how the starting parameters are arranged.

      A well written algorithm for generating random behavior should be convincing no matter how the starting parameters are arranged.

      True. Not only should they be convincing (i.e. have a suitable distribution) but the sequences shouldn't be guessable either.

      Your assertion that "computers are inherently deterministic" is mostly true from our normal perspective (otherwise they wouldn't be very useful.) The assertion leaves little hope, however, that computers can generate a random sequence that doesn't suffer from guessability. Fortunately, there is more to the story. Some operating systems do provide a mechanism for generating random numbers from input which is, in practice, impossible to reproduce or guess. This is done by collecting data from hardware events such as network device and disk interrupt latencies and then generating numbers based on the contents of this pool.

      -sauoq
      "My two cents aren't worth a dime.";
      

        For that matter, some computers have hardware that creates randomness from quantum effects. The most common is probably the southbridge in the i810 and later intel chipsets.


        Confession: It does an Immortal Body good.

          Some operating systems do provide a mechanism for generating random numbers from input which is, in practice, impossible to reproduce or guess. This is done by collecting data from hardware events such as network device and disk interrupt latencies and then generating numbers based on the contents of this pool.

        /dev/random and friends are useful for seeding PRNGs, not necessarily useful for all your random number needs (they tend to run out rather quickly: try generating a key of some size with GPG, and spending half an hour tapping the ctrl key to give it sufficient randomness). If you want reasonably strong (unguessable) randomness, without waiting for the OS entropy pool to fill up, you'll need to consider which PRNG you're using.

        And for that, I refer you to chapter 16 of Bruce Schneier's Applied Cryptography.

        --
        F o x t r o t U n i f o r m
        Found a typo in this node? /msg me
        The hell with paco, vote for Erudil!

Re: String randomness
by Aristotle (Chancellor) on Aug 16, 2002 at 01:15 UTC

    "No" is no valid answer to your question to begin with. :-)

    If you're using rand to pick a character, then it doesn't make a difference whether your array is sorted or not.

    Makeshifts last the longest.

Re: String randomness
by Anonymous Monk on Aug 16, 2002 at 01:14 UTC
    As a point of interest, I use the following code to generate a random password:
    sub GetRandomPassword { my ($passwordlen) = @_; if(!$passwordlen) { $passwordlen = 12; } $OK_CHARS='-a-zA-Z0-9_.@'; $randWord = ""; rand(time); # get first random value out of the way while( length($randWord) < $passwordlen ) { $achar = chr(int(rand(122))); $randWord .= $achar; $randWord =~ s/[^$OK_CHARS]//go; } return $randWord; }

      Why would you select random characters with values ranging from 0 to 121 and later delete the ones that you didn't want to use in the first place, when you already know with which characters (the ones in the string $OK_CHARS) you want to build your random word?

      You could just stick the characters you want to use in an array and pick the required number of random elements from the array, like so:

      sub randomPassword { my $length = shift || 12; my @OK_CHARS = ('a'..'z', 'A'..'Z', '0'..'9', qw[_ - . @]); my $password; for (1 .. $length) { $password .= $OK_CHARS[ int rand scalar @OK_CHARS ]; } return $password; }

      — Arien

      Much too complicated. Why generate a random character and then use a regex to delete it? Even Arien's good suggestion can be written briefer.
      my @pass_char = ('a'..'z', 'A'..'Z', 0 .. 9, qw(_ . @)); sub generate_password { my $len = shift || 12; my $pass; $pass .= $pass_char[rand @pass_char] for 1 .. $len; return $pass; }
      I can't resist golfing this a bit.. but the following is not necessarily for use in production. :-)
      my @pass_char = ('a'..'z', 'A'..'Z', 0 .. 9, qw(_ . @)); sub generate_password { return join '', map $pass_char[rand @pass_char], 1 .. (shift || 12 +); }
      ____________
      Makeshifts last the longest.
      rand(time); # get first random value out of the way
      What is the point of this line?

      Abigail