本文实例讲述了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