Re: regex elegance contest - validate a pw
by kvale (Monsignor) on Feb 11, 2004 at 10:23 UTC
|
Here is the test in a single rexexp:
#!/usr/bin/perl -w
use strict;
while (<DATA>)
{
chomp;
print "\n$_\n";
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{6,9}$/ ?
print "valid\n" :
print "invalid (Input must have at least one lowercase-, " .
"one uppercase-Char and one Number! (f.i.: \'12Three\')\
+n";
}
__DATA__
1245Za78
1245Za7b8
45a7b8
a78Z
12Three
kMdlOz
6KYX
diImMU1Y
ZNw4uWSht
jDqvSN
qVRR
le2WTQv
us1j3SerC
OZv0LtSJ
9qyscg
LbX7o74
80TeRHq
7YIiXnEV8
e1Yctl9
8iGoc
R87MeDCFz
ziTnlk
cziP
| [reply] [d/l] |
Re: regex elegance contest - validate a pw
by grinder (Bishop) on Feb 11, 2004 at 11:04 UTC
|
I wonder who has THE solution which combines shortness and elegance in a tremendous way
You do realise that it is not always possible to reconcile these two aims?
A single "one size fits all" test will not give you the chance of reporting why the password is no good. If this is not a problem, then my best shot looks like:
#! /usr/local/bin/perl -w
use strict;
while( <DATA> ) {
chomp;
my $ok = (
length $_ >= 5
and length $_ <=8
and /\d/
and /[A-Z]/
and /[a-z]/
);
print sprintf('%-12s', $_), ($ok ? 'valid' : 'invalid '), "\n";
}
I would probably break it up into separate test as shown elsewhere in this thread. You might also want to avoid reinventing the wheel and look at Data::Password::BasicCheck. Also, given that most people never bother to change the password they are given, you should also investigate Crypt::GeneratePassword. | [reply] [d/l] |
Re: regex elegance contest - validate a pw
by Anonymous Monk on Feb 11, 2004 at 10:22 UTC
|
KISS.
A single regex would not be clever
while (<DATA>)
{
chomp;
print "\n$_\n";
if ( length() < 5 ) {
print "too short\n"
}
elsif ( length() > 8 ) {
print "too long\n"
}
elsif ( not /\d/ ) {
print "need at least one digit\n"
}
elsif ( not /[a-z]/ ) {
print "need at least one lowercase letter\n"
}
elsif ( not /[A-Z]/ ) {
print "need at least one uppercase letter\n"
}
}
| [reply] [d/l] |
Re: regex elegance contest - validate a pw
by Abigail-II (Bishop) on Feb 11, 2004 at 10:55 UTC
|
Solutions have already been presented, but note that your
solution checks for more restrictive passwords than your requirements. Your regex disallows for instance
1d!Ot, which isn't disallowed by your requirements.
Abigail | [reply] |
Re: regex elegance contest - validate a pw
by Roger (Parson) on Feb 11, 2004 at 10:42 UTC
|
Ah, kvale has beaten me to the regex solution. Ok, I will post a slightly different one...
#!/usr/bin/perl -w
# vim: set tabstop=3
use strict;
while (<DATA>)
{
chomp;
print "$_ .. ";
if (m/^((?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).*)$
(??{ ! exists %{{qw! 5 0 6 0 7 0 8 0 !}}->{length($1)} })/x)
{
print "valid\n"
} else {
print "invalid\n"
}
}
__DATA__
1245Za78
1245Za7b8
45a7b8
a78Z
12Three
kMdlOz
6KYX
diImMU1Y
ZNw4uWSht
jDqvSN
qVRR
le2WTQv
us1j3SerC
OZv0LtSJ
9qyscg
LbX7o74
80TeRHq
7YIiXnEV8
e1Yctl9
8iGoc
R87MeDCFz
ziTnlk
cziP
| [reply] [d/l] |
Re: regex elegance contest - validate a pw
by EvdB (Deacon) on Feb 11, 2004 at 12:03 UTC
|
One immediate reaction is that if you are after secure passwords and provide an example then you will need to add this to your code:
if ( $password eq '12Three' ) {
warn "ALERT: unimaginative user detected, take evasive action";
}
--tidiness is the memory loss of environmental mnemonics
| [reply] [d/l] [select] |
Re: regex elegance contest - validate a pw
by fletcher_the_dog (Friar) on Feb 11, 2004 at 15:33 UTC
|
sub valid{
local $_ = shift;
return /\d/ && /[a-z]/ && /[A-Z]/ && /^.{5,8}$/
}
| [reply] [d/l] |
Re: regex elegance contest - validate a pw
by CountZero (Bishop) on Feb 11, 2004 at 16:16 UTC
|
Contrary to what many people believe, putting such (arbitrary) conditions on the format of passwords actually makes it easier to crack them.If you require the passwords to be at least 5 characters wide, you have decreased the number of possible passwords by approx. 63**4 (almost 16 million), i.e. all paswords with 4 or less characters of the range a-z A-Z 0-9 and "empty". Requiring at least one lower case character further reduces the password-space by 59% (37/63, i.e. none of A-Z 0-9 and "empty" are allowed in that position), id. for the required upper case character, and asking for at least one number finally lowers the total number of possible passwords by another 84% (53/63 - none of a-z A-Z and empty are allowed). In total the combination of these three conditions shrinks the number of allowed passwords to about one third of what was possible without these restrictions. My calculations may be a bit off as I did not take into acount the position of the restricted characters, but by and large it will be OK. There will still be a large number of possible passwords (which will probably defeat a brute force attack), but why limit the password-space, esp. since these rules do not guarantee "good" passwords at all? A typical birthday "8Jun1959" is a good password, whereas all say that one should avoid such easy to guess passwords.The only good password is therefore one which is randomly generated.
CountZero "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
| [reply] |
|
"The only good password is therefore one which is randomly generated."
Such passwords are extremely hard to guess, but there's a weakness: Giving out random passwords is just asking for people to write those hard-to-remember passwords down on Post-it(TM) notes. If someone sneaks into the office and finds a few written down passwords, the need to guess is eliminated completely.
| [reply] |
|
All too true, but you don't even need to look at your co-workers Post-It notes. Internet Explorer will remember your passwords for you! (and allow anyone in)
CountZero "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
| [reply] |
|
Contrary to what many people believe, putting such (arbitrary) conditions on the format of passwords actually makes it easier to crack them.
I suppose technically you are reducing the keyspace an attacker would need to attack the gain all passwords. The goal of something like this though isn't to try and make individual passwords harder to crack, but to limit the amount of passwords and attacker can gain easily (He's not going to try the entire keyspace regardless, it's to big). You want to limit the effectiveness of dictionary attackers, where an attacker can gain 80% of your password list in half an hour because all your users use common words as their passwords.
| [reply] |
|
Yes I understand that, but the artificial --IMHO-- restrictions do not guarantee that common words are excluded as probably most users will still use a common word, capitalize the first character and add a number at the end; or use their birthday or anything equally silly.
CountZero "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law
| [reply] |
Re: regex elegance contest - validate a pw
by leriksen (Curate) on Feb 12, 2004 at 07:45 UTC
|
Your test data haven't considered that \w also matches '_' , so this is an allowed character in your passwords - is that what you want ?
From perlre
In addition, Perl defines the following:
\w Match a "word" character (alphanumeric plus "_")
+++++++++++++++++
#!/usr/bin/perl
use warnings;use strict;use brain;
| [reply] |
|
% perl -e 'use locale; $_=q{äöü}; print qq{Locale aware!\n} if /^\w+$/
+;'
Results in:
Locale aware!
Thus, \w is bad when you really mean /[A-Za-z0-9]/. On the other hand, using the latter character class instead of \w is usually more of a problem for most applications. The best example is, I daresay, entering my last name in some form on the web that does this: Müller ;-)
Steffen
| [reply] [d/l] [select] |
|
I think it is also Unicode aware in 5.8+ so that introduces all sorts of variation - if Unicode is supported, \w usually refers to all alphanumberics - in fact you might see \w start to die out and things like unicode properties appear
$word = m/([\p{Letter}\p{Number}]+)/;
I think that is correct...
I know that in Java's regex package, \w == \A-Za-z0-9_\ only
I got most of this info from Friedl's Mastering Regular Expressions - if you dont own it - buy it and read it from chapters 1-7 - it is truely excellent, a standout book.
+++++++++++++++++
#!/usr/bin/perl
use warnings;use strict;use brain;
| [reply] [d/l] |
|
Re: regex elegance contest - validate a pw
by jsalvata (Initiate) on Feb 18, 2004 at 00:01 UTC
|
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{5,8}$/
merlyn, MidLifeXis, and tye gave me the idea in their answers to Operator for "these expressions, in any order". Hope you like it. | [reply] [d/l] |