soycharliente Posted July 25, 2010 Share Posted July 25, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/208845-regex-a-password/ Share on other sites More sharing options...
soycharliente Posted July 25, 2010 Author Share Posted July 25, 2010 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? Quote Link to comment https://forums.phpfreaks.com/topic/208845-regex-a-password/#findComment-1090966 Share on other sites More sharing options...
Psycho Posted July 26, 2010 Share Posted July 26, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/208845-regex-a-password/#findComment-1091297 Share on other sites More sharing options...
soycharliente Posted July 26, 2010 Author Share Posted July 26, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/208845-regex-a-password/#findComment-1091332 Share on other sites More sharing options...
Psycho Posted July 26, 2010 Share Posted July 26, 2010 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. Quote Link to comment https://forums.phpfreaks.com/topic/208845-regex-a-password/#findComment-1091398 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.