gkbrk/passwordstrength — pull request #2 by MaximeKjaer (2014-08-27 15:05:16+00:00)
Title: All rules + command line

Hello!

First of all I'd like to say that I found this repo on [lookingforpullrequests.com](http://www.lookingforpullrequests.com/). I liked the idea, and your code is IMO very readable, so I decided to expand on it :) I've included @jce-devel's changes as well, as they introduce some valuable funcionnality.

Let me know if you have any questions about it. I've included a big and detailed list of what I've done below.

# **Additions:**

- Implemented a table printing function. Here's an example, for the password ```jK6z4ddl3```:

count value
==================================================================
length 9 + 36
upper case letters 1 + 16
lower case letters 5 + 8
numbers 3 + 12
special characters 0 + 0
middle numbers or special characters 2 + 4
letters only no + 0
numbers only no + 0
repeating characters 1 - 1
consecutive upper-case letters 0 + 0
consecutive lower-case letters 2 - 4
consecutive numbers 0 + 0
sequential letters 0 + 0
sequential numbers 0 + 0
contains dictionary word no + 0
extra criteria yes + 8

- The table printing function **does not** print per default. Therefore, I added an argument to ```__init__()```: it's ```verbose```, and it defaults to False. The code to get a password's (for instance, for ```jK6z4ddl3```) score and have a verbose output is now:

.

score = passwordstrength.passwordstrength('jK6z4ddl3', True).get_score()

or:

score = passwordstrength.passwordstrength('jK6z4ddl3', verbose=True).get_score()

- I've also added a verbose argument to the command-line. Again, this defaults to ```false```
- Added ```__middle_score()```: 2 points for every number or special character in the middle of the password. WolframAlpha must have an error in their code, because they don't count special characters in this score, despite saying that they do. This addition **does** count special characters in the middle of the string to calculate the score.
- Added ```__consecutive_case_score()``` (removes points if there are consecutive lowercase, uppercase or numbers)
- Added ```__sequential_letters_score()``` (removes points if there's a sequence like 'abc' or 'xyz' in the password)
- Added ```__extra_score()``` (adds 8 points if the password is 8+ characters, has uppercase, lowercase and (numbers or special characters))
- Added a dictionary to the ```__dictionary_words_score()```. I made the dictionary specifically for this. It was originally made from almost 200 000 words in British and US English. I've since:
- Removed duplicates
- Removed words of length 1 and 2
- Set it all in lowercase
- Removed words that ended with ```'s``` (to mark possession, because they all had their equivalent without ```'s``` in the dictionary)
- Removed words that had substrings within the dictionary. For instance, if the password is ```artfully123```, it will match the words ```art```, ```artful``` **and** ```artfully```. That means that strictly, ```art``` is sufficient to determine that there is a dictionary word in the password.
The dictionary is now only 4650 words long.

# **Changes:**

- I've simplified ```__repeating_chars_score()```
- Slightly modified ```__lower_upper_case_score``` to follow WA's algorithm
- Included ```__numbers_only_score()``` in the ```__init___()``` function (the function existed, but the score wasn't calculated in the total)
- I'm loading the file outside the class. This way, I only have to load it once
- See commits; I've changed the setup.py and README.md to reflect changes.