1

I have a password field which should match the following conditions

  1. should have at least one letter and one digit
  2. should have minimum length of 5 and maximum length of 20

Also, I would like to know if regular expressions are the same for all languages?

Links to good tutorials to get started with Regular Expressions (assuming I have just a basic understanding) would also be nice.

Thank you

Soumya
  • 13,677
  • 6
  • 34
  • 49
Ibrahim Azhar Armar
  • 25,288
  • 35
  • 131
  • 207

2 Answers2

5

The min and max just use strlen.

The one character and one digit I would use preg_match:

$len = strlen($string);

if ($len < 5) {
     // too short
}elseif ( $len > 20) {
     // too long.
}elseif (!preg_match('#[0-9]#', $string)) {
     // does not contain a digit
}elseif (!preg_match('#[a-z]#i', $string)) {
     // does not have a character
} 

I like to break mine out to multiple checks so I can tell the user exactly what is missing. Some people prefer it bundled into one.

Jim
  • 18,673
  • 5
  • 49
  • 65
  • I like the idea of splitting it up and would vote you up if vote cap wasn't reached. – alex May 01 '11 at 14:17
  • No worries :) I just like this way because it makes it way easier when you want to use AJAX to display real time error messages. – Jim May 01 '11 at 14:19
  • do you think this is the good way? i personally liked the idea of bundling the code into one.. i thought that way it could be neat. – Ibrahim Azhar Armar May 01 '11 at 14:25
  • 1
    It all depends on your needs. But if you tell a user, "Sorry your password must be...insert long list of items here...please try again" a ton of users will be like, wtf I had that and that and that where did I go wrong? Where as you return them, "Sorry the password must be at least 5 characters." Then they have something more solid to go off of. This is just my personal opinion, if you want them all bundled, go for it. – Jim May 01 '11 at 14:29
  • @Ibrahim I usually consider myself alright with regex, but can't think of a regex that does this (the `{5,20}` quantifier is an issue with me). – alex May 01 '11 at 14:29
  • @alex i thought instead of splitting the validations with different if else condition my code would look neat if it is put into one function with fewer line of code, i have always been following the principle of writing fewer amount of code instead of making it lengthier. for example for username validation i used the following code. if(!preg_match('/^[A-Za-z0-9]{5,15}$/D', $this->username) || $this->checkUsernameAvailability($this->username)), you see just with one line of code i could validate the username and looks neat to me.. – Ibrahim Azhar Armar May 01 '11 at 14:40
  • @Brad you have got a valid point to argue with , but you see i am using two layered validation. one using Javascript or AJAX and another in PHP. i just want to make sure the data is passed in correctly even if someone disable the javascript in browser. while i intend to use a more robust validation for Front-end using javascript the above code is meant for use in PHP validation – Ibrahim Azhar Armar May 01 '11 at 14:42
  • @Ibrahim, You should be able to use this on the PHP or the AJAX side. It is a great tactic to use for either or, and it really does not pay to "duplicate" code that you can easily re-use. So yea, it should work just fine whether you are using it to verify against AJAX or PHP. – Jim May 01 '11 at 14:56
4

Regular expressions are a very good tool for password validation. Multiple rules can be applied using lookahead assertions (which work using AND logic) applied from the beginning of the string like so:

$re = '/
    # Match password with 5-20 chars with letters and digits
    ^                # Anchor to start of string.
    (?=.*?[A-Za-z])  # Assert there is at least one letter, AND
    (?=.*?[0-9])     # Assert there is at least one digit, AND
    (?=.{5,20}\z)    # Assert the length is from 5 to 20 chars.
    /x';
if (preg_match($re, $text)) {
    // Good password
}

Here's the Javascript equivalent:

var re = /^(?=.*?[A-Za-z])(?=.*?[0-9])(?=.{5,20}$)/;
if (re.test(text)) {
  // Good password
}

A good article regarding password validation using regex is: Password Strength Validation with Regular Expressions. (Although his final expressions include an erroneous dot-star at the beginning - see my comment on his blog).

Also note that regex syntax does vary from language to language (but most are converging on the Perl syntax). If you really want to know regex (in the Neo: "I know Kung-Fu" sense), then there is no better way than to sit down and read: Mastering Regular Expressions (3rd Edition) By Jeffrey Friedl.

Additional: A good argument can be made that password validation should be split up into multiple tests which allows the code to give specific error messages for each type of validation error. The answer provided here is meant to demonstrate one correct way to validate multiple rules using just one regular expression.

Happy regexing!

ridgerunner
  • 33,777
  • 5
  • 57
  • 69