🍎作者:塵世鏡花戀
🍏日期:2023 1.25 p.m.
🍓主題:用python檢測密碼強度并生成強密碼(防暴力破解)
點選目錄可直達源碼哦,本文章沒有用任何偏難知識,也适用于Python入門新手練習 ~
目錄
- (一)場景描述
- (二)使用的密碼強度規則
- (三)Python Show Time!
-
- (1)檢測密碼強度
- (2)生成強密碼
- (四)Demo以及運作截圖
- (五)小結,告别
(一)場景描述
日常生活中往往離不開輸入密碼,雖然有實名認證,以及其他的郵箱驗證,驗證碼驗證etc…,但是擁有一個相當強度的密碼還是必要的,是以本文章的核心内容就是運用python檢測輸入密碼的強度,并生成指定個數的強密碼。
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiIXZ05WZj91YpB3InVGcq5CN4QjZkRWM2kzMidTMkdjM3EDMlhzM0YDMmBTM5YjYz8CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpeg)
(二)使用的密碼強度規則
詳情請見 密碼強度規則,本文采用裡面的正常版密碼規則,具體如下:
- 密碼長度: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 | 弱 |
非常弱 |
開整!
(三)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一戰到底!