🍎作者:尘世镜花恋
🍏日期:2023 1.25 p.m.
🍓主题:用python检测密码强度并生成强密码(防暴力破解)
点击目录可直达源码哦,本文章没有用任何偏难知识,也适用于Python入门新手练习 ~
(一)场景描述
日常生活中往往离不开输入密码,虽然有实名认证,以及其他的邮箱验证,验证码验证etc…,但是拥有一个相当强度的密码还是必要的,所以本文章的核心内容就是运用python检测输入密码的强度,并生成指定个数的强密码。
(二)使用的密码强度规则
详情请见 密码强度规则,本文采用里面的常规版密码规则,具体如下:
- 密码长度:5 分: 小于等于 4 个字符–> 10 分: 5 到 7 字符-- 25 分: 大于等于 8 个字符
- 字母:–> 0 分: 没有字母–> 10 分: 全都是小(大)写字母20 分: 大小写混合字母
- 数字:–> 0分: 没有数字–> 10分: 1 个数字–> 20分: 大于等于 3个数字
- 符号:–> 0分: 没有符号–> 10分: 1个符号–> 25分: 大于1个符号
- 奖励:–> 2分: 字母和数字–> 3分: 字母、数字和符号–> 5分: 大小写字母、数字和符号
分数规则:
分数 | 强度 |
---|---|
>=90 | 非常安全 |
>=80 | 安全 |
>=70 | 非常强 |
>=60 | 强 |
>=50 | 一般 |
>=25 | 弱 |
0 | 非常弱 |
开整!
(三)Python Show Time!
首先设定可输入的字符,基本都是键盘上能打出来的合法字符,提示用户输入并检测其合法性。
这里直接用 海象运算符 将str转换为list,并输出到屏幕。
然后转换password为集合,用difference求出与其他集合的差集,本来以为不能将列表作为参数输入,但是发现也不会报错,于是就不改了(美汁汁~)。如果不存在差集,返回None,布尔值False,not语句转换为True,输出是否合法,并返回bool,这里稍后会用到。
合法性检验函数内勉强最复杂的也就是列表推导式,这里也是偷个懒,生成大写的字母表。
#python 3.9
print("可使用字符:",end='')
print(list0:=list('1234567890'),end='')
print(list1:=list('qwertyuiopasdfghjklzxcvbnm'),end='')
print(list2:=list(r"\`~!@#$%^&*()_-+=|{}[]:;>?/',."))
list2.append('"')
#合法性
def legal(p):
list3=[i.upper() for i in list1]
if not set(p).difference(list0,list1,list2,list3):
print("Your passsword is legal.")
return True
else:
print("Your passsword is illegal.")
return False
(1)检测密码强度
以下代码的注释介绍均写在这几点里(仅针对初学者):
- len_password函数,检测密码长度,其实这个并不适用于网站注册的密码,因为一般网站注册会限定长度,而这里的规则明显是越长越好
- letter函数,检测字母,这里的逻辑是在遍历password时单独将字母存入一个列表,然后比较转换为大小写前后的值是否相同,如果相同说明全为大写或全为小写,否则混有大小写。
- number函数,用try-except来加入数字到新的列表,这种方法与letter里的异曲同工,如果不是int则程序一声不吭(pass)。
- symbol函数,与上面的检验合法性相似,不再赘述。
#奖励累加变量,满足大小写字母混合,变量+1
reward=0
#密码长度
def len_password(p):
if len(p)<=4:
return 5
elif len(p)<=7:
return 10
else:
return 25
#字母
def letter(p):
count=0
i_list = []
for i in p:
if i.isalpha():
count+=1
i_list.append(i)
if count==0:
return 0
elif str(i_list).upper()==str(i_list) or str(i_list).upper()==str(i_list):
return 10
else:
return 20
#大小写混合,奖励+1
reward+=1
#数字
def number(p):
num_list=[]
try:
for i in p:
if int(i):
num_list.append(i)
except:
pass
if not num_list:
return 0
elif len(num_list)<3:
return 10
else:
return 20
#number("1123wde")
def symbol(p):
a=set(p).difference(list0,list1)
if not a:
return 0
elif len(a)==1:
return 10
else:
return 25
#print(symbol("123e3238??!"))
奖励部分加在用户的输入循环中,最终输出密码强度,对于这部分代码,我觉得大部分没有什么好解释的,就算新手也能搞明白。
强调一下奖励加入的部分,要注意结合奖励规则来看待这串代码
输入exit即可退出循环。
print("Made By 尘世镜花恋.")
while 1:
account=input("Input your passsword:")
if account=='exit':
input("Press any keys to exit.")
break
else:
if legal(account):
#没试过这样偷懒的方法,今天试试
func_list=[len_password(account),letter(account),number(account),symbol(account)]
#奖励加入,逻辑完全依照规则
if reward==1 and func_list[2]!=0 and func_list[3]!=0:
func_list.append(5)
elif func_list[1]!=0 and func_list[2]!=0:
func_list.append(2)
elif func_list[1]+func_list[2]+func_list[3]==0:
func_list.append(3)
else:
pass
total=sum(func_list)
print("总分数:",total)
print("您的密码强度等级:",end='')
if total>=90:
print("非常安全")
elif total>=80:
print("安全")
elif total>=70:
print("非常强")
elif total>=60:
print("强")
elif total>=50:
print("一般")
elif total>=25:
print("弱")
else:
print("非常弱")
else:
continue
(2)生成强密码
由于实现两个功能的代码都比较长,所以我单独放在不同文件,想要连贯的客官可以拼接实现
这个的格式可以根据代码自己修改一番,格式有多种,寻找高强度密码就交给各位客官啦~
#密码格式:大写字母*n+小写字母*m+数字*4
import random,re,string
import win32gui,win32con,win32api
import pyperclip
#输入密码长度
count=input('输入密码长度(范围8-20):')
#以下分别为数字长度,大写字母长度,小写字母长度
numlen = 4
Cstrlen = random.randint(1,int(count)-5)
Lstrlen = int(count) - numlen - Cstrlen
passwd = ''
##密码第一段为大写字母
truestr = True
pwCstr = ''
while truestr:
Cstr = random.sample(string.ascii_uppercase,Cstrlen)
pwCstr = ''.join(Cstr)
if re.search('O',pwCstr) or re.search('I',pwCstr):
continue
else:
truestr = False
##密码第二段为小写字母
truestr = True
pwLstr = ''
while truestr:
Lstr = random.sample(string.ascii_lowercase, Lstrlen)
pwLstr = ''.join(Lstr)
if re.search('l',pwLstr):
continue
else:
truestr = False
##密码后4位为数字
tmp = random.sample(string.digits, 4)
##最后将密码都整合起来
passwd = pwCstr + pwLstr + ''.join(tmp)
print(passwd+'\n')
win32api.MessageBox(0, '新密码:\n'+passwd+'\n已复制到剪切板,请注意保存!\n', "提示",win32con.MB_ICONASTERISK)
pyperclip.copy(passwd)
(四)Demo以及运行截图
check_passwd.py
#python 3.9
print("可使用字符:",end='')
print(list0:=list('1234567890'),end='')
print(list1:=list('qwertyuiopasdfghjklzxcvbnm'),end='')
print(list2:=list(r"\`~!@#$%^&*()_-+=|{}[]:;>?/',."))
list2.append('"')
#合法性
def legal(p):
list3=[i.upper() for i in list1]
if not set(p).difference(list0,list1,list2,list3):
print("Your passsword is legal.")
return True
else:
print("Your passsword is illegal.")
return False
#奖励累加变量,满足大小写字母混合,变量+1
reward=0
#密码长度
def len_password(p):
if len(p)<=4:
return 5
elif len(p)<=7:
return 10
else:
return 25
#字母
def letter(p):
count=0
i_list = []
for i in p:
if i.isalpha():
count+=1
i_list.append(i)
if count==0:
return 0
elif str(i_list).upper()==str(i_list) or str(i_list).upper()==str(i_list):
return 10
else:
return 20
#大小写混合,奖励+1
reward+=1
#数字
def number(p):
num_list=[]
try:
for i in p:
if int(i):
num_list.append(i)
except:
pass
if not num_list:
return 0
elif len(num_list)<3:
return 10
else:
return 20
#number("1123wde")
def symbol(p):
a=set(p).difference(list0,list1)
if not a:
return 0
elif len(a)==1:
return 10
else:
return 25
#print(symbol("123e3238??!"))
print("Made By 尘世镜花恋.")
while 1:
account=input("Input your passsword:")
if account=='exit':
input("Press any keys to exit.")
break
else:
if legal(account):
#没试过这样偷懒的方法,今天试试
func_list=[len_password(account),letter(account),number(account),symbol(account)]
#奖励加入,逻辑完全依照规则
if reward==1 and func_list[2]!=0 and func_list[3]!=0:
func_list.append(5)
elif func_list[1]!=0 and func_list[2]!=0:
func_list.append(2)
elif func_list[1]+func_list[2]+func_list[3]==0:
func_list.append(3)
else:
pass
total=sum(func_list)
print("总分数:",total)
print("您的密码强度等级:",end='')
if total>=90:
print("非常安全")
elif total>=80:
print("安全")
elif total>=70:
print("非常强")
elif total>=60:
print("强")
elif total>=50:
print("一般")
elif total>=25:
print("弱")
else:
print("非常弱")
else:
continue
out_passwd.py
#密码格式:大写字母*n+小写字母*m+数字*4
import random,re,string
import win32gui,win32con,win32api
import pyperclip
#输入密码长度
count=input('输入密码长度(范围8-20):')
#以下分别为数字长度,大写字母长度,小写字母长度
numlen = 4
Cstrlen = random.randint(1,int(count)-5)
Lstrlen = int(count) - numlen - Cstrlen
passwd = ''
##密码第一段为大写字母
truestr = True
pwCstr = ''
while truestr:
Cstr = random.sample(string.ascii_uppercase,Cstrlen)
pwCstr = ''.join(Cstr)
if re.search('O',pwCstr) or re.search('I',pwCstr):
continue
else:
truestr = False
##密码第二段为小写字母
truestr = True
pwLstr = ''
while truestr:
Lstr = random.sample(string.ascii_lowercase, Lstrlen)
pwLstr = ''.join(Lstr)
if re.search('l',pwLstr):
continue
else:
truestr = False
##密码后4位为数字
tmp = random.sample(string.digits, 4)
##最后将密码都整合起来
passwd = pwCstr + pwLstr + ''.join(tmp)
print(passwd+'\n')
win32api.MessageBox(0, '新密码:\n'+passwd+'\n已复制到剪切板,请注意保存!\n', "提示",win32con.MB_ICONASTERISK)
pyperclip.copy(passwd)
运行结果截图:
运行结果良好,暂时没发现bug,强弱程度判断比较准确,Perfect !
(五)小结,告别
看了一下,这篇文章足足肝了我几个小时,是我实战项目4的两倍字数(7093),但是我还是觉得内容质量很高,我相当满意,各位客官如果觉得有用给个三连哦~
PS:
本文可能会是我退出相当长时间的最后发表,毕竟已经到备战高考的时候了(掐指算算还有1年多吧),开学还有个期末考试,寒假作业还没写,内心其实慌得一批,但是我不后悔,这段时间学到了很多,遇到很多大佬,初三的夏季,我遇到了CSDN,这次我希望高三的那个夏季,且等我高考完毕,来CSDN一战到底!