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

Hi Guys, I am writing a script to create user accounts on my server, I dont want the users to create their onw passwords - instead i want some kind of random password generator to do it. the password needs to be greater that 6 chars/numbers and must contain a combination of uppercase characters and numbers. Would someone be kind enough to work their majic on this one? Thanks

Replies are listed 'Best First'.
Re: Passwords
by Abigail-II (Bishop) on Aug 02, 2002 at 10:12 UTC
    my @chars = ('a' .. 'z', 'A' .. 'Z', 0 .. 9); my $password = do {{ local $_ = join "" => map {$chars [rand @chars]} 1 .. 8; redo unless /[a-z]/ && /[A-Z]/ && /\d/; $_; }};
    Abigail
      One might wonder, how often does the redo get excuted? Well, we're doing a redo if the generated password doesn't contain a lowercase letter, or it doesn't contain an uppercase letter, or it doesn't contain a digit.

      The chance of not containing a lowercase letter is the same as the chance the password only contains uppercase letters or digits, which is (36/62)^8. The chance of not containing an uppercase letter is of course the same. Similary, the chance of not containing a digit is (52/62)^8.

      Now, the chance of doing a redo is sligthly less than the sum of these three chances, because than you would count the chance of the password containing only lowercase letters, only uppercase letters, or only digits twice. The chance of containing only lowercase letters, or only uppercase letters is (26/62)^8. The chance of containing only digits is (10/62)^8.

      Hence the chance of doing a redo is

      (36/62)^8+(36/62)^8+(52/62)^8-(26/62)^8-(26/62)^8-(10/62)^8
      which, according to bc, is roughly
      .2687742319
      or just over one in four.

      So, what is the expected number of iterations you have to do to calculate a password? Let p be the chance of having to do a redo. Then the number of iterations is

      (1 - p) + 2 (1 - p) p + 3 (1 - p) p^2 + 4 (1 - p) p^3 + ... = (1 - p) (1 + 2 p + 3 p^2 + 4 p^3 + ...) = 1 - p ----- (p + 2 p^2 + 3 p^3 + 4 p^4 + ...) = p 1 - p p 1 ----- ------ 2 = ----- p (1 - p) 1 - p
      which is roughly
      1.3675666854
      Tests suggests the calculated number might be correct.

      Abigail

        Wow, wicked flashback to AP Stats....
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Passwords
by Dog and Pony (Priest) on Aug 02, 2002 at 09:50 UTC
    For a seven (>6) character password:
    print join '', (0..9, 'A'..'Z', 'a'..'z')[rand 62] for(1..7);
    (Slightly altered version of the example at crypt).

    If you want to have variable length passwords, try adding a rand statement inside the for, that adds a random number to the 7.

    Hope that helps.


    You have moved into a dark place.
    It is pitch black. You are likely to be eaten by a grue.
      sorry to bother you again, but how do i put the generated password into a variable i.e $password. I have tried doing it using $password = join '', ....... But it just returns the first character of the generated password when i print it. Thanks
        Actually, there is, I see now, an error in my code which is the reason you can't do that right off the bat. My mistake for using print to test it with, since print happily takes arrays as input...

        Anyhow, you want Abigail-II's version below in either case, since it a) works, b) is much neater and c) makes sure you always have at least one each of numbers, lower- and uppercase characters (I missed that wish too). :)


        You have moved into a dark place.
        It is pitch black. You are likely to be eaten by a grue.
Re: Passwords
by Anonymous Monk on Aug 02, 2002 at 09:41 UTC
    and also lowercase characters...sorry