Python实现的密码强度检测器示例


Posted in Python onAugust 23, 2017

本文实例讲述了Python实现的密码强度检测器。分享给大家供大家参考,具体如下:

密码强度

密码强度如何量化呢?

一个密码可以有以下几种类型:长度、大写字母、小写字母、数字以及特殊符号。

显然,密码包含的特征越多、长度越长,其强度也就越高。

我们设置几个等级来评测密码强度,分别是:terrible, simple,
medium, strong

不同的应用可能对密码强度的要求不一样,我们引入最小程度(min_length)和最小特征数(min_types),作为可配置选项。

这样我们就可以检测密码包含的特征,特征与密码之间的关系可以简单定义为:

特征数 强度
小于最小长度 terrible
常用密码或规则的密码 simple
小于最小特征数 medium
大于或等于最小特征数 strong

另:常用的1万个密码点击此处本站下载

代码实现

check.py

# 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: 用于单元测试

# 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 相关文章推荐
Python入门篇之字符串
Oct 17 Python
Python pickle模块用法实例分析
May 27 Python
使用Python将数组的元素导出到变量中(unpacking)
Oct 27 Python
浅谈python import引入不同路径下的模块
Jul 11 Python
《Python学习手册》学习总结
Jan 17 Python
PYQT5设置textEdit自动滚屏的方法
Jun 14 Python
Python程序打包工具py2exe和PyInstaller详解
Jun 28 Python
python如何使用jt400.jar包代码实例
Dec 20 Python
序列化Python对象的方法
Aug 01 Python
python3.8动态人脸识别的实现示例
Sep 21 Python
python 如何停止一个死循环的线程
Nov 24 Python
Python离线安装各种库及pip的方法
Nov 28 Python
python+selenium+autoit实现文件上传功能
Aug 23 #Python
Django与JS交互的示例代码
Aug 23 #Python
python paramiko模块学习分享
Aug 23 #Python
定制FileField中的上传文件名称实例
Aug 23 #Python
基于python元祖与字典与集合的粗浅认识
Aug 23 #Python
Python 多线程Threading初学教程
Aug 22 #Python
Python3实现抓取javascript动态生成的html网页功能示例
Aug 22 #Python
You might like
全国FM电台频率大全 - 4 山西省
2020/03/11 无线电
天津市收音机工业发展史
2021/03/04 无线电
探讨php中遍历二维数组的几种方法详解
2013/06/08 PHP
PHP 动态生成静态HTML页面示例代码
2014/01/15 PHP
详解提高使用Java反射的效率方法
2019/04/29 PHP
Javascript 的addEventListener()及attachEvent()区别分析
2009/05/21 Javascript
javascript getElementsByClassName函数
2010/04/01 Javascript
javascript 兼容所有浏览器的DOM扩展功能
2012/08/01 Javascript
Javascript优化技巧之短路表达式详细介绍
2015/03/27 Javascript
jquery解析XML及获取XML节点名称的实现代码
2016/05/18 Javascript
详解Jquery 遍历数组之$().each方法与$.each()方法介绍
2017/01/09 Javascript
Vue添加请求拦截器及vue-resource 拦截器使用
2017/11/23 Javascript
qrcode生成二维码微信长按无法识别问题的解决
2019/04/04 Javascript
vue-router源码之history类的浅析
2019/05/21 Javascript
详解vue 组件
2020/06/11 Javascript
Vue 解决父组件跳转子路由后当前导航active样式消失问题
2020/07/21 Javascript
javascript实现简单留言板案例
2021/02/09 Javascript
[06:25]第二届DOTA2亚洲邀请赛主赛事第二天比赛集锦.mp4
2017/04/03 DOTA
python合并文本文件示例
2014/02/07 Python
python fabric使用笔记
2015/05/09 Python
Python+Opencv识别两张相似图片
2020/03/23 Python
浅谈python之高阶函数和匿名函数
2019/03/21 Python
python笔记之mean()函数实现求取均值的功能代码
2019/07/05 Python
解决selenium+Headless Chrome实现不弹出浏览器自动化登录的问题
2021/01/09 Python
Python+MySQL随机试卷及答案生成程序的示例代码
2021/02/01 Python
HTML5 解析规则分析
2009/08/14 HTML / CSS
印度尼西亚手表和包包商店:Urban Icon
2019/12/12 全球购物
法国购买二手电子产品网站:Asgoodasnew
2020/03/27 全球购物
公司廉洁自律承诺书
2014/03/27 职场文书
运动会演讲稿
2014/05/07 职场文书
部门群众路线教育实践活动对照检查材料思想汇报
2014/10/07 职场文书
师德师风事迹材料
2014/12/20 职场文书
投资申请报告
2015/05/19 职场文书
世界上超棒的8种逻辑思维
2019/08/06 职场文书
MySQL sql_mode的使用详解
2021/05/08 MySQL
Java中的随机数Random
2022/03/17 Java/Android