2

Sorry to all if this code is poor as I am just following through a book to and modifying it for my school project as I just started php less than a month ago.

I am trying to understand what this validation mean but can't seem to comprehend it full as I am new with php.

Code:

if (preg_match ('/^(\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}$/', $_POST['pass']) ) {

        //$p = mysqli_real_escape_string ($dbc, $_POST['pass']);
        $p = $_POST['pass'];
        $sticky_password = $p;

        } else {
        $error['pass'] = 'Please enter a valid password!';
        }

Any help would be really appreciated! Thanks!

Thank you very much.. :)

GitKidd
  • 252
  • 1
  • 3
  • 16
  • 4
    Read: http://www.regular-expressions.info/ and http://php.net/preg_match – Sverri M. Olsen Apr 16 '13 at 21:22
  • 3
    would fail any of my passwords they always contain special characters are and are always over 20+ characters long. don't force me to have a crap password on your site. –  Apr 16 '13 at 21:23
  • @Dagon Hello. :) , sorry if this code is poor as i just copied it from a php book by larry ullman (effortless ecommerce) as I am fairly new to php and just trying to develop a small project for my programming subject at my college. – GitKidd Apr 16 '13 at 21:27
  • 1
    You could replace `/^[a-z\d_]{2,20}$/i` with `/^\w{2,20}$/` – HamZa Apr 16 '13 at 21:27
  • 1
    Why use regex to validate a username or password? All you're doing is inconvenience the user. If your trying to prevent hacking there are better techniques. – Krik Apr 16 '13 at 21:34
  • restrict bad passwords, not good ones. set a minimum but no maximum and allow all characters. *Perhaps* enforce the existence of the 3 character types –  Apr 16 '13 at 21:36
  • Hi guys, sorry.. Im only 17 and I just started programming last month.. I am just trying to follow through a book and I'm really sorry if these codes are bad as I only got them from a book and just trying to understand it for my school project. - also, if any of you would be kind enough, please help me with a good regex for validating passwords.. thank you.. – GitKidd Apr 16 '13 at 21:41
  • we are trying to help, 17 or 77, you have to help your self first. –  Apr 16 '13 at 21:57
  • 2
    @GitKidd: Most code in books is just exemplary, it is not meant to be copy and pasted to be *really used* later on. Take care. – hakre Apr 16 '13 at 22:23
  • Thanks for all your help! :) i have managed to do the registration process successful now.. yey! :) .. Thanks to all. :) – GitKidd Apr 16 '13 at 22:27

2 Answers2

3

We have the following regex: /^(\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}$/

  1. The first and last / are the delimiters.

  2. ^ -> The start, $ -> The end

    Which means if input is abc and your regex is /^bc$/, it won't get matched since bc is not at the beginning.

  3. Now we have (\w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*){6,20}

    The {6,20} is the quantifier part, which means 6 up to 20 times.

  4. Let's break the regex further: \w*(?=\w*\d)(?=\w*[a-z])(?=\w*[A-Z])\w*

    Let's provide some equivalents:

    1. \w => [a-zA-Z0-9_]
    2. \d => [0-9]
    3. * => zero or more times
    4. (?=) Is a lookahead assertion. Example /a(?=b)/ this will match any "a" followed by "b"

    5. The purpose of those lookaheads:

      • (?=\w*\d) => check if there is a digit
      • (?=\w*[a-z]) => check if there is a lowercase letter
      • (?=\w*[A-Z]) => check if there is a uppercase letter
      • Let's take (?=\w*\d): The \w* is just there as a "workaround" in case there is [a-zA-Z0-9_]* before a digit

In the end, this regex just makes sure that the input:

  1. is 6 to 20 characters long
  2. that there is minimal: 1 lowercase, 1 uppercase and 1 digit
  3. that the allowed characters are letters (upper and lowercase (a-z,A-Z)), digits and underscore.

Three interesting sites www.regexper.com, www.regular-expressions.info and www.regex101.com.

Note: Don't restrict passwords, you have to hash them anyway. Take a look here or check the other questions on SO.

Community
  • 1
  • 1
HamZa
  • 13,530
  • 11
  • 51
  • 70
  • 2
    `{6,20}` means 6 up to 20 **times** (not characters), and in this pattern has little effect since the group it applies to can be zero-width. – Phill Sparks Apr 16 '13 at 23:09
  • 1
    @PhillSparks Thanks for pointing that out :) – HamZa Apr 16 '13 at 23:17
  • 1
    Thanks @HamZaDzCyberDeV . you have been a very great help and thank you for being kind in taking time to answer my problem. :) thanks for the point Phil. – GitKidd Apr 16 '13 at 23:56
  • @GitKidd Ah this is also a good site to test/practice/learn regex http://regex101.com – HamZa Apr 17 '13 at 00:12
0

Actually this pattern matches all passwords with at least 3 characters (a digit, an upper case and a lower case in any order) without a length limit (except for the regex engine). All characters must be word characters (ie: from the class \w).

The author intention was probably to match all passwords between 6 and 20 word characters with at least one digit, one upper case and one lower case, as the quantifier and the lookaheads suggest.

In short this pattern is wrong, but probably aims what this classical password validation pattern does:

^(?=\w*[A-Z])(?=\w*[a-z])(?=\w*\d)\w{6,20}$

or this one without all redundant \w:

^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)\w{6,20}$

Explanation: lookaheads are zero-width assertions, they don't consume characters, they are only tests. Consequence each of them are performed from the start of the string since they are anchored to the ^. If each lookahead succeeds, then \w{6,20} is tested always from the start of the string to know if it contains only between 6 and 20 word characters. $ means the end of the string.

As said in comments, this pattern comes from the book "Effortless E-commerce" first edition, by Larry Ullman.

Even if the author wrotes:

"And, admittedly, even I often have to look up the proper syntax for patterns, but this one requires a high level of regular expression expertise."

and even if I disagree with the second part of the sentence, I think this pattern is a simple typo. However I don't know if this one has been corrected in the second edition.

Casimir et Hippolyte
  • 83,228
  • 5
  • 85
  • 113
  • This pattern will match any string that has at least 1 number, lower case letter and upper case letter, and contains only word characters `[a-zA-Z0-9_]`. It gets confusing because of use of `\w*` here, but the `{6,20}` actually has no effect, since it can be 6 to 20 of nothing (zero-width). – Phill Sparks Apr 16 '13 at 23:08