-1

I am writing a function that is checking if the password meets requirements. The requirements are:

  1. At least 8 characters
  2. At least 1 upper case letter
  3. At least 1 lower case letter
  4. At least 1 number
  5. At least 1 of these special character: @$!#%*?&

Here is my code:

passwordCriteria = re.compile(r'''
        (?=.*[a-z])
        (?=.*[A-Z])
        (?=.*\d)
        (?=.*[@$!%*#?&])
        [A-Za-z\d@$!#%*?&]{8,}$
    ''', re.VERBOSE)

If I enter the password: Newyork@1995. The password should be meet the requirements.

However, when I remove this condition from the code above (?=.*\d). The password still meets the requirements apparently.

How is that possible? doesn't this lookahead check (?=.*\d) ensure that there is at least 1 number in the password?

  • Yes, it does. But your argument logic is incorrect; simply because you are no longer using lookahead does not mean that integer should not match. E.g. - you have integer matching in the length checking part as well. – stackoverflowusrone Mar 01 '20 at 20:00

1 Answers1

0

Your regex accepts Newyork@1995 because your character class [A-Za-z\d@$!#%*?&] contains \d, but without the lookahead assertion, there will be no enforcement that a digit must be present. But there is another problem.

Having guaranteed that your password meets all your requirements other than the 8-character length one with your 4 lookahead assertions, all you really need for matching is to ensure that the input is at least 8 characters long with: .{8,}:

import re

passwordCriteria = re.compile(r'''
        (?=.*[a-z])
        (?=.*[A-Z])
        (?=.*\d)
        (?=.*[@$!%*#?&])
        .{8,}$
    ''', re.VERBOSE)

m = passwordCriteria.match('aA$7xxxxxxxxx')
print(m)
m = passwordCriteria.match('aA$xxxxxxxxx')
print(m)

Prints:

<_sre.SRE_Match object; span=(0, 13), match='aA$7xxxxxxxxx'>
None

Using this character class specification as you did is completely redundant with the lookahead assertions and can lead to potential maintenance issues. Besides, presumably the user is allowed to enter other characters besides the "required" ones, such as a hyphen, but your regex would not allow that.

Booboo
  • 18,421
  • 2
  • 23
  • 40