3
\$\begingroup\$

I am creating a code which checks a user inputted password and gives points based on it. One of the points is: If it has 3 letters adjacent/consecutive on the QWERTY UK keyboard then it will be -5 points. e.g "qwerty" will be -20 points for "qwe" "wer "ert" "rty". I have got a solution to this but I was wondering if there is any way of improving it.

input = input("What is your password?")
qwerty = 'qwertyuiopasdfghjklzxcvbnm'
lower = input.lower()
for idx in range(0, len(lower) - 2):
    test_seq = lower[idx:idx + 3]
    if test_seq in qwerty:
        points -= 5
print(points)
\$\endgroup\$
1
  • 2
    \$\begingroup\$ I have rollbacked the last edit as removing code from the question makes it off-topic for Code Review. \$\endgroup\$ Commented Oct 7, 2017 at 21:46

3 Answers 3

5
\$\begingroup\$

According to my interpretation, your solution does not actually meet the specification:

If it has 3 letters adjacent/consecutive on the QWERTY UK keyboard then it will be -5 points

For example, pas does not have three adjacent keys on a QWERTY keyboard, yet it gets penalized by your code. On the other hand, your code fails to detect backwards adjacent sequences such as ewq.

\$\endgroup\$
2
  • \$\begingroup\$ If you don't mind, could you please share any ideas of how to doing this. Thank You \$\endgroup\$ Commented Oct 8, 2017 at 15:22
  • \$\begingroup\$ @olivierclotherp: Just a quick stab at fixing the problem with minimal effort for code change: change your single 'qwertyuiopasdfghjklzxcvbnm' string into a list of three strings ('qwertyuiop' , 'asdfghjkl' , 'zxcvbnm') so that you don't get false positives such as pas. \$\endgroup\$
    – Flater
    Commented Nov 3, 2017 at 10:53
3
\$\begingroup\$

Instead of iterating over the entire string for every sequence of 3 characters, you can create a set of all possible 3-letter sequences on the QWERTY UK keyboard beforehand, and then check if any of those sequences exist in the user's inputted password.

input_password = input("What is your password?")
qwerty_sequences = {'qwe', 'wer', 'ert', 'rty', 'tyu', 'yui', 'uio', 
'iop', 'asd', 'sdf', 'dfg', 'fgh', 'ghj', 'hjk', 'jkl', 'zxc', 'xcv', 
'cvb', 'vbn', 'bnm'}
lower_password = input_password.lower()

points = 0
for seq in qwerty_sequences:
if seq in lower_password:
    points -= 5

print(points)

This implementation creates a set of all possible 3-letter sequences on the QWERTY UK keyboard and then iterates over each sequence, checking if it exists in the user's inputted password.

I've created the website keyboardtester.io by using the same concept.

\$\endgroup\$
2
\$\begingroup\$

I am sure your code works, but you missed initializing points to zero in what you shared here.

You can write these 2 lines:

input = input("What is your password?")
lower = input.lower()

into a single one:

lowercase_password = input('What is your password?').lower()

Your current program accepts short passwords, including empty strings which makes your passwords vulnerable to to attacks such as password guessing and brute force. To remedy to that, you can improve your code with:

password_length = 0
while(password_length < 16): # Change 16 to what is acceptable by the security standards
   lowercase_password = input('What is your password? ').lower()
   password_length = len(lower)

There are other elements to take in consideration if your goal is to assess the strength of a password.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ I would also add that redefining the input function to be a string was a bad idea. \$\endgroup\$ Commented Oct 8, 2017 at 0:19
  • \$\begingroup\$ Yes, that is very true. \$\endgroup\$ Commented Oct 8, 2017 at 5:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.