0,0 → 1,105 |
#!/usr/bin/env python |
|
""" |
Simplistic Password Strength Checker. |
""" |
|
# Based on |
# <http://www.geekwisdom.com/dyn/passwdmeter> |
# |-> <http://www.geekwisdom.com/js/passwordmeter.js> |
# (this is mostly based on the scoring system explained there, |
# and not on the actual implementation) |
|
import re |
import string |
import sys |
|
WEAK_THRESHOLD = 16 |
MEDIOCRE_THRESHOLD = 25 |
STRONG_THRESHOLD = 35 |
VERY_STRONG_THRESHOLD = 45 |
|
def check(pw): |
''' |
check(str) -> ( int score, str strength category, str description) |
''' |
score = 0 |
verdict = 'weak' |
log = '' |
# Password length |
length = len(pw) |
if length == 0: |
return ( 0, 'weak', 'empty password' ) |
if length < 5: |
score += 3 |
elif length < 8: |
score += 6 |
elif length < 16: |
score += 12 |
else: |
score += 18 |
log += '%d points for length (%d)\n' % (score, length) |
# Letters |
locase = re.search('[a-z]', pw) |
upcase = re.search('[A-Z]', pw) |
if (locase and upcase): |
score += 7 |
log += '7 points for mixed case\n' |
elif locase: |
score += 5 |
log += '5 points for all-lowercase letters\n' |
elif upcase: |
score += 5 |
log += '5 points for all-uppercase letters\n' |
else: # No letters at all |
pass |
# Numbers |
hasnums = re.search('\d', pw) |
if hasnums and re.search('\d.*\d.*\d', pw): |
score += 7 |
log += '7 points for at least three numbers\n' |
elif hasnums: |
score += 5 |
log += '5 points for at least one number\n' |
# Special Characters |
sch = string.punctuation |
hasspecial = re.search('[%s]' % sch, pw) |
if hasspecial and re.search('[%s].*[%s]' % ( sch, sch), pw): |
score += 10 |
log += '10 points for at least two special characters\n' |
elif hasspecial: |
score += 5 |
log += '5 points for at least one special character\n' |
# Combos |
hasletters = re.search('([a-z]|[A-Z])', pw) |
if hasnums and hasletters: |
score += 1 |
log += '1 combo point for mixed letters and numbers\n' |
if hasspecial: |
score += 2 |
log += '2 combo points for mixed letters, numbers and special characters\n' |
if upcase and locase: |
score += 2 |
log += '2 combo point for mixed case letters, numbers and special characters' |
# Verdict |
if score < WEAK_THRESHOLD: |
verdict = 'very weak' |
elif score < MEDIOCRE_THRESHOLD: |
verdict = 'weak' |
elif score < STRONG_THRESHOLD: |
verdict = 'mediocre' |
elif score < VERY_STRONG_THRESHOLD: |
verdict = 'strong' |
else: |
verdict = 'stronger' |
|
return ( score, verdict, log ) |
|
if __name__ == '__main__': |
for candidate in sys.argv[1:]: |
( score, verdict, descr ) = check(candidate) |
print '%s: %s\t%s' % ( candidate, score, verdict ) |
sys.stderr.write(descr) |
|
# vim:set ts=4 et ai: # |
|
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
Added: svn:keywords |
+Rev Id Date |
\ No newline at end of property |