Jump to content

Recommended Posts

Many months ago, I was asking a question about doing regex on a password. Someone posted some code that I do not understand at all. The original problem I was trying to solve was using regex to check for some password requirements. Now, for a different site, I'm making the requirements a bit more technical, and I feel like one of the solutions offered the first time might help me, but I would really like to actually understand it instead of just using it. Plus, I think it needs to be tweaked for the more strenuous requirements this time around.

 

The requirements that I have this time are:

Must be between 6 and 16 characters in length.

Must start with a letter.

Must contain at least one character from 3 of the 4 classes:

‣ Upper case alphabetic: A-Z

‣ Lower case alphabetic: a-z

‣ Numeric: 0-9

‣ Special: ! @ # $ % ^ & * ( ) + = . _ -

 

Here are the two functions that someone gave the first go round:

function pwCheck($password)
{
  $validChars = "/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9!@#$%^&*()_.-])[A-Za-z0-9!@#$%^&*()_.-]{6,16}$/";
  return (preg_match($validChars, $password));
}

function pwCheck($password)
{
  $validChars = "/^[A-Za-z0-9!@#$%^&*()_.-]{6,16}$/";
  $classCheck = '/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9!@#$%^&*()_.-])/';
  return (preg_match($validChars, $password) && preg_match($classCheck, $password));
}

 

I understand the second function more. This is what I've got so far on my own, but I don't know how to make it satisfy the 3 out of 4 check.

function isPassword($password)
{
$return = FALSE;
$characters = "/^[A-Za-z0-9!@#$%^&*()+=._-]{6,16}$/";
$classes = '/(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*()+=._-])/';
if (preg_match($characters, $password) && preg_match($classes, $password)) { $return = TRUE; }
return $return;
}

 

Any help? Thanks.

Link to comment
https://forums.phpfreaks.com/topic/208845-regex-a-password/
Share on other sites

After trying to make it work, I started going a different direction I guess. I started writing this:

$regex = '/^([A-Za-z]+[([A-Za-z]*)0-9]+[([A-Za-z]*)._-]+){6,16}$/';

But I'm getting a PHP error for unmatched parenthesis at offset 39.

 

I don't know why. Any ideas?

Link to comment
https://forums.phpfreaks.com/topic/208845-regex-a-password/#findComment-1090966
Share on other sites

I doubt your error has anything to do with that line since all your parens are within a string. The error is most likely somewhere above that line.

 

As to your particular requirement I don't think it is possible to do it with a single regex expression due to your last requirement to require 3 out of four different "classes" of characters. You can validate that all classes are present, but I can't think of a way to validate that at least 3 out of the 4 are present. Well, not without creating an exceptionally long expression. I would suggest just using RegEx to validate that ALL the characters are withint he acceptable classes and do the other validations with non regex.

Link to comment
https://forums.phpfreaks.com/topic/208845-regex-a-password/#findComment-1091297
Share on other sites

Sounds like I need to talk to the people I'm working with. Maybe combing uppercase and lowercase and checking for all classes would be better. Then I could use this?

function isPassword($password)
{
$return = FALSE;
$characters = "/^[A-Za-z0-9!@#$%^&*()+=._-]{6,16}$/";
$classes = '/(?=.*[A-Za-z])(?=.*[0-9])(?=.*[!@#$%^&*()+=._-])/';
if (preg_match($characters, $password) && preg_match($classes, $password)) { $return = TRUE; }
return $return;
}

For the error, when I commented out that regex and just put a regular echo statement, everything was fine. I don't know why it threw an error, but I do believe it was the regex line.

Link to comment
https://forums.phpfreaks.com/topic/208845-regex-a-password/#findComment-1091332
Share on other sites

This should meet your needs. I did some testing, but suggest you do some as well to ensure it meets your needs.

 

function isValidPassword($password)
{
    //Validate that 1st char is alpha, ALL characters are valid and length is correct
    if(preg_match("/^[A-Z][A-Z0-9\!\@\#\$\%\^\&\*\(\)\+\=\.\_\-]{5,15}$/i", $password)===0)
    {
        return false;
    }
    //Validate that password has at least 3 of 4 classes
    $classes = 0;
    $classes += preg_match("/[A-Z]/", $password);
    $classes += preg_match("/[a-z]/", $password);
    $classes += preg_match("/[0-9]/", $password);
    $classes += preg_match("/[!@#$%^&*()+=._-]/", $password);
    return ($classes >= 3);
}

 

Note the RegEx uses {5, 15} for the length because it doesn't include the first character that has different requirements than the rest.

Link to comment
https://forums.phpfreaks.com/topic/208845-regex-a-password/#findComment-1091398
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.