Testing a new password

M

Mark Drummond

I have a chunk of code that generates a random password form a specified
set of characters. Once the password is generated I want to test it for
certain characteristics and if it does not meet those characteristics
then I want to toss it and start again. What I am working with looks
something like (not necessarily correct code below!):

sub newpass {
my $pass
my $badpass = 1;
my $rand;
my $passlen = $_[0];
$passlen = 8 if !$passlen;
my @chars = qw/ a b c ...
A B C ...
0 1 2 ... /;

while ($badpass == 1) {
$pass = "";
for (my $i=0; $i < $passlen; $i++) {
$rand = int(rand $#chars+1);
$pass .= $chars[$rand];
}
#
# INSERT PASSWORD TESTS HERE
#
$badpass = 0;
}

return $pass
}

I wanted to do something like the following for my tests:

# test for at least one lowercase char
next if $pass =~ /[[:lower:]]/;
# test for at least one uppercase char
next if $pass =~ /[[:upper:]]/;
# test for at least one digit
next if $pass =~ /[[:digit:]]/;

But my program just spins in an infinite loop. So clearly I have no idea
what I am doing!!

Any tips?!

Mark
 
M

Mark Drummond

Jim said:
Mark Drummond said:
I have a chunk of code that generates a random password form a specified
set of characters. Once the password is generated I want to test it for
certain characteristics and if it does not meet those characteristics
then I want to toss it and start again. What I am working with looks
something like (not necessarily correct code below!):

sub newpass {
my $pass
my $badpass = 1;
my $rand;
my $passlen = $_[0];
$passlen = 8 if !$passlen;
my @chars = qw/ a b c ...
A B C ...
0 1 2 ... /;

while ($badpass == 1) {
$pass = "";
for (my $i=0; $i < $passlen; $i++) {
$rand = int(rand $#chars+1);
$pass .= $chars[$rand];
}
#
# INSERT PASSWORD TESTS HERE
#
$badpass = 0;
}

return $pass
}

I wanted to do something like the following for my tests:

# test for at least one lowercase char
next if $pass =~ /[[:lower:]]/;
# test for at least one uppercase char
next if $pass =~ /[[:upper:]]/;
# test for at least one digit
next if $pass =~ /[[:digit:]]/;

But my program just spins in an infinite loop. So clearly I have no idea
what I am doing!!

You are rejecting any password that contains a lowercase or uppercase
character or a digit, and they all do.

Try:

next unless $pass =~ /[[:lower]]/;

or

next if $pass !~ /[[:lower]]/;

etc.

Sorry about that. I don't know if this is correct or not but my test
lines were actually:

next if $pass =~ /[[:^lower:]]/;

Which I was treating as the negation.

Nonetheless, I followed your suggestion above and it worked. Thanks!

Mark
 
J

John W. Krahn

Mark said:
I have a chunk of code that generates a random password form a specified
set of characters. Once the password is generated I want to test it for
certain characteristics and if it does not meet those characteristics
then I want to toss it and start again. What I am working with looks
something like (not necessarily correct code below!):

sub newpass {
my $pass
my $badpass = 1;
my $rand;
my $passlen = $_[0];
$passlen = 8 if !$passlen;
my @chars = qw/ a b c ...
A B C ...
0 1 2 ... /;

while ($badpass == 1) {
$pass = "";
for (my $i=0; $i < $passlen; $i++) {
$rand = int(rand $#chars+1);
$pass .= $chars[$rand];
}
#
# INSERT PASSWORD TESTS HERE
#
$badpass = 0;
}

return $pass
}

I wanted to do something like the following for my tests:

# test for at least one lowercase char
next if $pass =~ /[[:lower:]]/;
# test for at least one uppercase char
next if $pass =~ /[[:upper:]]/;
# test for at least one digit
next if $pass =~ /[[:digit:]]/;

But my program just spins in an infinite loop. So clearly I have no idea
what I am doing!!

Any tips?!

$ perl -le'
sub newpass {
my $passlen = $_[ 0 ] || 8;
my @chars = ( q[a] .. q[z], q[A] .. q[Z], 0 .. 9 );
my $pass;
$pass = join q[], map $chars[ rand @chars ], 1 .. $passlen
until $pass =~ y/a-z// && $pass =~ y/A-Z// && $pass =~ y/0-9//;
$pass;
}
print newpass 10 for 1 .. 10;
'
SXH35wmcgG
besJUyjs4S
DLEiG9VrFI
teWFIT0U7U
ec3wODsDgk
K9JfO7swpB
5ptyCLRPAU
48w5T9qo7z
pC2aBddYSh
2tCYrE65Y6



John
 
D

Dave Weaver

At 2006-06-15 10:58AM said:
for (my $i=0; $i < $passlen; $i++) {
$rand = int(rand $#chars+1);
$pass .= $chars[$rand];
}

You could write this more tersely as:
$pass .= $chars[int rand @chars] for (1..$passlen);

Or even more tersely (but, IMO, equally readably) as:
$pass .= $chars[rand @chars] for 1..$passlen;
 
M

Mark Drummond

John said:
$ perl -le'
sub newpass {
my $passlen = $_[ 0 ] || 8;
my @chars = ( q[a] .. q[z], q[A] .. q[Z], 0 .. 9 );
my $pass;
$pass = join q[], map $chars[ rand @chars ], 1 .. $passlen
until $pass =~ y/a-z// && $pass =~ y/A-Z// && $pass =~ y/0-9//;
$pass;
}
print newpass 10 for 1 .. 10;
'

This seems to be generating proper passwords but I do get a warning:

sub newpassword {
my $password;
my $password_length = $_[0] || 10;
my @chars = ( q[a] .. q[z], q[A] .. q[Z], 0 .. 9 );

$password = join q[], map $chars[rand @chars], 1 .. $password_length
until $password =~ y/a-z// and $password =~ y/A-Z// and $password =~
y/0-9//;
return $password;
}

Use of uninitialized value in transliteration (tr///) at file2ldap.pl
line 111
, <FILE_USERS> line 344.

It seems to work fine, but I don't like to see warnings if I can avoid them.

Mark.
 
J

John W. Krahn

Mark said:
John said:
$ perl -le'
sub newpass {
my $passlen = $_[ 0 ] || 8;
my @chars = ( q[a] .. q[z], q[A] .. q[Z], 0 .. 9 );
my $pass;
$pass = join q[], map $chars[ rand @chars ], 1 .. $passlen
until $pass =~ y/a-z// && $pass =~ y/A-Z// && $pass =~ y/0-9//;
$pass;
}
print newpass 10 for 1 .. 10;
'

This seems to be generating proper passwords but I do get a warning:

sub newpassword {
my $password;
my $password_length = $_[0] || 10;
my @chars = ( q[a] .. q[z], q[A] .. q[Z], 0 .. 9 );

$password = join q[], map $chars[rand @chars], 1 .. $password_length
until $password =~ y/a-z// and $password =~ y/A-Z// and
$password =~ y/0-9//;
return $password;
}

Use of uninitialized value in transliteration (tr///) at file2ldap.pl
line 111
, <FILE_USERS> line 344.

It seems to work fine, but I don't like to see warnings if I can avoid
them.

Change:

my $password;

To:

my $password = '';

And you won't get that warning message.



John
 
B

Bart Van der Donck

Jim said:
[...]
For a slightly better approach, I would start the password with a
lowercase letter, an uppercase letter, and a digit, add as many
characters as need to meet the length requirement, and then do a random
shuffle of the characters.

One other suggestion is to avoid characters like these in passwords:

0 vs O (zero vs capital O)
1 vs l vs I (integer one vs lower case L vs capital i)
...

The display of those will obviously depend on the font, but many users
don't copy/paste passwords.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,139
Latest member
JamaalCald
Top