-2

I made a password strength checker Code:

import re

upper = re.compile(r'[A-Z]')
lower = re.compile(r'[a-z]')
digit = re.compile(r'[0-9]')
special_char = re.compile(r'[~!@#$%^&*()]')

# text = 'd3F#$%^&232sdsGDFD'
text = input("Enter a password to check it's strength\n")

digit_check = digit.search(text)
upper_check = upper.search(text)
lower_check = lower.search(text)
special_char_chk = special_char.search(text)

if digit_check and upper_check and lower_check and special_char_chk and len(text)>=8:
    print("Valid password\nPassword is:" + text)
else:
    print("Innvalid")

I tried to make it as short at my level. How far can I reduce the number of code lines?

  • [Obligatory xkcd](https://www.xkcd.com/936/) – Daniel Mar 24 '18 at 08:48
  • 1
    I'm voting to close this question as off-topic because it is a better fit for https://codereview.stackexchange.com – Bart Kiers Mar 24 '18 at 08:50
  • @Bart Kiers that is *not* true. Code Review is not intended for help with code obfuscation / golfing: "... asking about code-golfing, obfuscation, or similar is off-topic." ([source](https://codereview.stackexchange.com/help/on-topic)) – Daniel Mar 24 '18 at 08:51
  • 1
    If the target is code-golfing, then maybe it should be moved to https://codegolf.stackexchange.com/ - but I think the the issue here is that the OP is not clearly stating his objective (what is the benefit of "reducing the number of code lines" here?) – carrdelling Mar 24 '18 at 09:13
  • @Coal_, I am/was not under the impression that the OP wanted to obfuscate the code. Just to write it in less LOC. "Reducing" != "Obfuscating". – Bart Kiers Mar 24 '18 at 13:14
  • @Bart Kiers All questions whose *primary concern* is shortening, code-golfing, or similar, are off topic on CRSE. It's okay to ask 'How could I simplify this piece of code?', but it's not okay to ask 'How could I write this in 10 lines, instead of 11?'. – Daniel Mar 24 '18 at 13:24
  • You may benefit from [Reference - Password Validation](https://stackoverflow.com/questions/48345922/reference-password-validation/) – ctwheels Mar 26 '18 at 13:33

2 Answers2

6

Shorter != better. But yes, it can be made both shorter and better, e.g.:

if (all(re.search(p, text) for p in ['[A-Z]', '[a-z]', '[0-9]', '[~!@#$%^&*()]']) and
        len(text) >= 8):
Alex Hall
  • 34,833
  • 5
  • 57
  • 89
  • Random cycle golfing: If you use a tuple instead of a list, it can be built at compile time. But that hardly matters as the code will compile the regexes on each run anyway. Main argument against: [] stand out against the () used for calls. By the way, the outer parenthesis aren't needed in your `if` (though I guess they're for the line break, and do look better than backslash). – Yann Vernier Mar 24 '18 at 09:15
  • 1
    Python caches regexes, so it doesn't compile every time. The outer parentheses are needed unless I add a slash at the end of the line. – Alex Hall Mar 24 '18 at 09:18
0

You can definitely combine the expressions into one regex:

expr = re.compile('(^[^A-Z]$)|(^[^a-z]$)|(^[^0-9]$)|(^[^~!@#$%^&*()]$)|(^.{0,7}$)')
if expr.search('a99@999B'):
    print('Invalid')
else:
    print('Valid')

Note that the boolean values in the expression are combined using the equation a & b = !a | !b. So basically, this is looking for:

if(no_lowercase or no_uppercase or no_digit or no_symbol or 7chars_or_fewer):
  #it's invalid
else:
  #it's valid
ernest_k
  • 44,416
  • 5
  • 53
  • 99
  • Your idea is interesting. But complex logic in regexes is difficult to get right and generally a bad idea. Case in point: you forgot a `^` before `[^A-Z]` so if I add a character to the end of your password that isn't an uppercase letter it becomes invalid. – Alex Hall Mar 24 '18 at 09:50
  • @AlexHall thanks, don't know how it got lost... Good point about complexity, but it's a nice alternative for scenarios where it's a good idea to compile and search only once. – ernest_k Mar 24 '18 at 09:53