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

Can sombody please tell me how to make @myarray (in the codesample bel +ow) contain chars a-z, and 1-9 without actually typing them? (like wi +th some cool tr//something? ###################################### @myarray=("a","b","c"); srand; while($i<8) { $index=rand(@myarray); $mysamplepass="$mysamplepass"."@myarray[$index]"; $i=$i+1; } print $mysamplepass; ######################################

Replies are listed 'Best First'.
(Ovid) Re: General quesion
by Ovid (Cardinal) on Aug 07, 2000 at 21:51 UTC
    Let's clean up your code a little bit, too:
    #!/usr/bin/perl -w use strict; my @myarray=('a'..'z','A'..'Z','1'..'9'); my $mysamplepass; for (1..8) { $mysamplepass .= $myarray[rand(@myarray)]; } print $mysamplepass;
    Notes:
    • The .. operator lets you specificy a range.
    • The .= is shorthand for concatenation. Similar shorthands are += and -= (though there are others). $x = $x + 3 is functionally equivalent to $x += 3.
    • I've included upper-case characters in the range as they dramatically increase security on passwords by increasing possible permutations.
    Hope this helps! Let me know if you have any questions.

    Cheers,
    Ovid

    Update: Aargh!!! jlistf touched on most of these points while I was composing this. I need to type faster :(

      My turn to go Aargh!!! I just wrote pretty much this same code and I missed the for (1..8) optimization.

      Of course, I have an excuse since my code actually accepts the size for the password and if they go with a real large password, I would have to wait for the list to be created. Yeah, that's my excuse and I'm sticking to it. :-) Yes, I know it's a weak excuse, but it was the best I could come up with.

      One question though. When using a random number it returns a decimal. Does using it as an array index automagically int() it? 'Cause in my code, I explicitly call int around my rand call.

        When using a random number it returns a decimal. Does using it as an array index automagically int() it?

        Take a look at the scalar we're creating:

        $myarray[rand(@myarray)];
        You'll notice that rand is being passed @myarray. Since rand is expecting a scalar, @myarray is interpreted in a scalar context. Therefore, it returns the length of the array (52 in this case), which will cause rand to generate a random number from 0 to 51, which fits the array index quite nicely. Perhaps this would have been more clear:
        $myarray[rand($#myarray)];
        Cheers,
        Ovid
Re: General quesion
by lhoward (Vicar) on Aug 07, 2000 at 21:36 UTC
some more points.
by jlistf (Monk) on Aug 07, 2000 at 21:43 UTC
    you'll hear it eventually and get burned by it soon, so here it is:

    use strict and use warnings.
    this will force you to declare all your variables. eventually, this will come in very handy. its better to get started early before you get seriously burned later on.
    some other notes:
    • you don't have to call srand. perl will do this for you.
    • the while loop can be turned into a for (1..8) loop. this will get rid of the $i control variable which does not do anything.

    update (to Ovid): slowpoke. :)

      > you don't have to call srand. perl will do this for you.

      Technically, only versions of perl 5.004 and higher will call srand for you. Also note that if you are using a pre-5.004 version, srand alone uses time as the seed, which is generally Not Very Random. It will probably do in this case. So calling srand explicitly is actually the safest, most portable way to do it. Or you could be really proper and call srand depending on the version of perl detected.

      Also, here is a simpler way to create a random string. Just has to use this one today, actually. (Yes, it's in the Perl Cookbook, but I came up with it on my own :p)

      @letters = ('A'..'Z','a'..'z',0..9,qw(! # $ % ^ | _)); $randomstring = join("", @letters[map {rand @letters} (1..8)]);
RE: General quesion
by lindex (Friar) on Aug 08, 2000 at 15:10 UTC
    #!/usr/bin/perl -w use strict; my(@array) = ('a'..'z',0..9); my($pass); for(1..8) { $pass .= $array[int(rand(scalar(@array)))]; } print $pass; exit();



    lindex
    /****************************/ jason@gost.net, wh@ckz.org http://jason.gost.net /*****************************/
      This line:
      $pass .= $array[int(rand(scalar(@array)))];
      during a code review would have me scratching my head, pondering whether the author was getting paid by the character. I'd probably gently suggest, in the nicest but firmest tones, that it be replace with the much simpler and exactly effectively equivalent:
      $pass .= $array[rand @array];

      -- Randal L. Schwartz, Perl hacker

        Well ok maybe I never tested all the ways to get a rand
        element out of a list :\
        I was just throwing in my two cents.
        Why the way I did it? Because it made since to me the first
        I ever tried todo such a thing :)



        lindex
        /****************************/ jason@gost.net, wh@ckz.org http://jason.gost.net /*****************************/