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 | [reply] [d/l] |
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
| [reply] [d/l] [select] |
Wow, wicked flashback to AP Stats....
| [reply] |
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. | [reply] [d/l] [select] |
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
| [reply] |
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.
| [reply] |
and also lowercase characters...sorry | [reply] |