本文实例讲述了Python实现的密码强度检测器。分享给大家供大家参考,具体如下:
密码强度
密码强度如何量化呢?
一个密码可以有以下几种类型:长度、大写字母、小写字母、数字以及特殊符号。
显然,密码包含的特征越多、长度越长,其强度也就越高。
我们设置几个等级来评测密码强度,分别是:terrible, simple,
medium, strong。
不同的应用可能对密码强度的要求不一样,我们引入最小程度(min_length)和最小特征数(min_types),作为可配置选项。
这样我们就可以检测密码包含的特征,特征与密码之间的关系可以简单定义为:
特征数 | 强度 |
---|---|
小于最小长度 | terrible |
常用密码或规则的密码 | simple |
小于最小特征数 | medium |
大于或等于最小特征数 | strong |
另:常用的1万个密码点击此处本站下载。
代码实现
check.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
# coding: utf-8
"""
check
Check if your password safe
"""
import re
# 特征
NUMBER = re. compile (r '[0-9]' )
LOWER_CASE = re. compile (r '[a-z]' )
UPPER_CASE = re. compile (r '[A-Z]' )
OTHERS = re. compile (r '[^0-9A-Za-z]' )
def load_common_password():
words = []
with open ( "10k_most_common.txt" , "r" ) as f:
for word in f:
words.append(word.strip())
return words
COMMON_WORDS = load_common_password()
# 管理密码强度的类
class Strength( object ):
"""
密码强度三个属性:是否有效valid, 强度strength, 提示信息message
"""
def __init__( self , valid, strength, message):
self .valid = valid
self .strength = strength
self .message = message
def __repr__( self ):
return self .strength
def __str__( self ):
return self .message
def __bool__( self ):
return self .valid
class Password( object ):
TERRIBLE = 0
SIMPLE = 1
MEDIUM = 2
STRONG = 3
@staticmethod
def is_regular( input ):
regular = ' '.join([' qwertyuiop ', ' asdfghjkl ', ' zxcvbnm'])
return input in regular or input [:: - 1 ] in regular
@staticmethod
def is_by_step( input ):
delta = ord ( input [ 1 ]) - ord ( input [ 0 ])
for i in range ( 2 , len ( input )):
if ord ( input [i]) - ord ( input [i - 1 ]) ! = delta:
return False
return True
@staticmethod
def is_common( input ):
return input in COMMON_WORDS
def __call__( self , input , min_length = 6 , min_type = 3 , level = STRONG):
if len ( input ) < min_length:
return Strength( False , "terrible" , "密码太短了" )
if self .is_regular( input ) or self .is_by_step( input ):
return Strength( False , "simple" , "密码有规则" )
if self .is_common( input ):
return Strength( False , "simple" , "密码很常见" )
types = 0
if NUMBER.search( input ):
types + = 1
if LOWER_CASE.search( input ):
types + = 1
if UPPER_CASE.search( input ):
types + = 1
if OTHERS.search( input ):
types + = 1
if types < 2 :
return Strength(level < = self .SIMPLE, "simple" , "密码太简单了" )
if types < min_type:
return Strength(level < = self .MEDIUM, "medium" , "密码还不够强" )
return Strength( True , "strong" , "密码很强" )
class Email( object ):
def __init__( self , email):
self .email = email
def is_valid_email( self ):
if re.match( "^.+@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$" , self .email):
return True
return False
def get_email_type( self ):
types = [ 'qq' , '163' , 'gmail' , '126' , 'sina' ]
email_type = re.search( '@\w+' , self .email).group()[ 1 :]
if email_type in types:
return email_type
return 'wrong email'
password = Password()
|
test_check.py: 用于单元测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# coding: utf-8
"""
test for check
"""
import unittest
import check
class TestCheck(unittest.TestCase):
def test_regular( self ):
rv = check.password( "qwerty" )
self .assertTrue( repr (rv) = = "simple" )
self .assertTrue( '规则' in rv.message)
def test_by_step( self ):
rv = check.password( "abcdefg" )
self .assertTrue( repr (rv) = = "simple" )
self .assertTrue( '规则' in rv.message)
def test_common( self ):
rv = check.password( "password" )
self .assertTrue( repr (rv) = = "simple" )
self .assertTrue( '常见' in rv.message)
def test_medium( self ):
rv = check.password( "ahj01a" )
self .assertTrue( repr (rv) = = 'medium' )
self .assertTrue( '不够强' in rv.message)
def test_strong( self ):
rv = check.password( "asjka9AD" )
self .assertTrue( repr (rv) = = 'strong' )
self .assertTrue( '很强' in rv.message)
# 测试邮箱
def test_email( self ):
rv = check.Email( "123@gmail.com" )
self .assertEqual(rv.is_valid_email(), True )
def test_email_type( self ):
rv = check.Email( "123@gmail.com" )
types = [ 'qq' , '163' , 'gmail' , '126' , 'sina' ]
self .assertIn(rv.get_email_type(), types)
if __name__ = = '__main__' :
unittest.main()
|
希望本文所述对大家Python程序设计有所帮助。
原文链接:http://blog.csdn.net/xushao_movens/article/details/53844013