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

Of course, generating a random string of chars is simple when you do it the obvious way : pick a number beetween 1 and 26 for each letter of the string, and make up the string.
I was wondering if there was a more clever way to do it though. Anyone has hints ?

Thanks all

  • Comment on Generating a random string of chars, easily.

Replies are listed 'Best First'.
Re: Generating a random string of chars, easily.
by broquaint (Abbot) on Nov 14, 2002 at 15:17 UTC
    The range operator will come in handy for this
    die("Usage: $0 LENGTH") unless @ARGV; my @alpha = ( a .. z, A .. Z ); my $randstr = join '', map $alpha[rand @alpha], 0 .. shift; print "random string: $randstr", $/;

    HTH

    _________
    broquaint

      Oh my god, it's so clear once you saw it !
      I keep forgeting about those shortcuts like the range operator, I was starting to write:
      my @alpa =('a','b',...) ;
      BTW isn't a int missing before the rand @alpha ?
      I mean, it works without it but it seems strange no?
        BTW isn't a int missing before the rand @alpha ?
        I mean, it works without it but it seems strange no?
        Since arrays indices are integer based, so perl automagically converts the given float to an int. I should imagine it would be rather awkward accessing the 2.53815239812875th element of an array ;)
        HTH

        _________
        broquaint

Re: Generating a random string of chars, easily.
by BrowserUk (Patriarch) on Nov 14, 2002 at 16:28 UTC

    This works quite nicely as it's self documenting and the return can be assigned directly to a scalar.

    #! perl -slw use strict; sub rndStr{local $"=''; "@_[map{rand$#_} 1 .. shift]"; } print rndStr 40, 'a'..'z'; print rndStr 40, 'A'..'Z'; print rndStr 40, 0..9; print rndStr 40, 'a'..'z', 'A'..'Z', 0..9; __END__ C:\test>212859 rxshjxkkgjqhyhukodujhmghpwujqteudxrvxsxo MCRFGFETIDWEDHBWVSDKGJVMOEDEWKIJXRKAAGSQ 3288712881034147833223824725784363650780 EL0A5PsUCzPb8Sh3IyFGrCKElRPPeilXTPQDreKz C:\test>

    Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
    Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
    Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
    Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

      Okay this one is a little fancier. I knew that by asking a question (even this one wich is trivial) I would learn a lot!

      Thanx BrowserUk
      Sorry to admit that I don't understand the magic in it. Could you explain?

        Sure. This is the same subroutine but opened out and using named parameters to explain the intermediate steps.

        sub rndStr{ # When an array is interpolated in a string $" is used to seperate + the values # By setting it (locally) to '', we ensure that the string doesn't + have spaces or # anything else inserted between the characters. local $" = ''; my ( $len, @chars_to_pick_from) = @_; # @picks will end up with as many random values as requested. my @picks = map{ # Generate random numbers bewteen 0 and # the number of chars supplied to pick from rand $#chars_to_pick_from # do it as many times as request } 1 .. $length; # Using an array slice interpolated in quotes to construct the str +ing # @picks contains the random indices, the slice picks them out of +the # array of choices past in. The resultant string is returned as a +scalar. "@chars_to_pick_from[@picks]"; }

        In the short version above, I'm just using the @_ array, (and shift to get the first parameter) and doing the whole thing in a single step rather than all seperated out.

        Hope that helps.


        Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
        Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
        Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
        Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

      OKay, I have another challenge then.
      What about doing the same without using an array initialized with the chars we wanna pick ( ie (a..z) ? Would there be a solution?

        Adjust the numbers and name to suit.

        sub rndlc{local$"=''; "@{[map{chr(97+int rand 26)} 1 .. shift]}" } print rndlc 20; hgvuemeeezgjwbzjmgezo

        Okay you lot, get your wings on the left, halos on the right. It's one size fits all, and "No!", you can't have a different color.
        Pick up your cloud down the end and "Yes" if you get allocated a grey one they are a bit damp under foot, but someone has to get them.
        Get used to the wings fast cos its an 8 hour day...unless the Govenor calls for a cyclone or hurricane, in which case 16 hour shifts are mandatory.
        Just be grateful that you arrived just as the tornado season finished. Them buggers are real work.

Re: Generating a random string of chars, easily.
by jmcnamara (Monsignor) on Nov 14, 2002 at 15:36 UTC

    Here is one way:     perl -le 'print map{(a..z)[rand 26]} 0..rand 10'

    --
    John.

      Thanx :-).
      PLaying golf? ok a little too trivial.