[Python] 纯文本查看 复制代码
import random
import string
from typing import Optional
import PySimpleGUI as sg
import pyperclip as pc
def getRandom(leng: int, typnum: int):
num_list = []
# 如果密码长度和密码复杂度一致,就默认设置为1
if leng == typnum:
return [1 for _ in range(typnum)]
for i in range(typnum, 0, -1):
num_list.append(random.randint(1, leng - sum(num_list) - i))
num_list[num_list.index(min(num_list))] += leng - sum(num_list)
num_list.sort(reverse=True)
return num_list
def randmima(key: list[str],
leng: int,
special: Optional[str] = '~!@#$%^&*()-_=+?><.,'):
# 字典项
atomDict = {
'lowers': string.ascii_lowercase,
'uppers': string.ascii_uppercase,
'numbers': string.digits,
'sym': special if special else string.punctuation
}
# 获取每个原子项分的长度数组
if len(key) > leng:
raise KeyError("密码长度不能小于复杂度个数")
numList = getRandom(leng, len(key))
seclist = []
for index, value in enumerate(numList):
seclist += random.choices(atomDict[key[index]], k=value)
# 重新排序
random.shuffle(seclist)
return "".join(seclist)
def batchPwd(optionDict: dict) -> list:
atomList = ['lowers', 'uppers', 'numbers', 'sym']
secList = []
atom = [
key for key, value in optionDict.items() if key in atomList and value
]
# 判断原子数据是否为空
if not atom:
return ["至少选择一项"]
random.shuffle(atom)
for index in range(int(optionDict['pwdCount'])):
secList.append(
[f'{index + 1}.', randmima(atom, int(optionDict['pwdlength']), special=optionDict['spclistr'])])
# return "\n".join(secList)
return secList
def main():
# 图形界面
pdict = {
'uppers': True,
'lowers': True,
'numbers': True,
'sym': True,
'pwdlength': 12,
'pwdCount': 5,
'spclistr': None
}
pwds = batchPwd(pdict)
sg.theme("Dark Brown")
optional = {'font': "MicrosoftYaHei 14", "margins": (10, 10)}
config_option_spcil1 = [
sg.Checkbox("大写字母", default=True, key="uppers", enable_events=True),
sg.Checkbox("小写字母", default=True, key="lowers", enable_events=True),
sg.Checkbox("数字", default=True, key="numbers", enable_events=True)
]
config_spcil2_option = [
sg.Checkbox('', default=True, key="sym", enable_events=True),
sg.Input('.,$#@!^&*-_=+:;?',
size=(25, 1),
key="spclistr",
disabled=False,
enable_events=True)
]
config_option = [
sg.Text("密码组成: "),
sg.Column([config_option_spcil1, config_spcil2_option])
]
config_resgen_btn = [sg.Button("重新生成", key='-regeneration-')]
btn_column = [sg.Column([config_resgen_btn], justification="right")]
pwd_length_option = [
sg.Text("密码长度: "),
sg.Slider(range=(4, 50),
default_value=pdict['pwdlength'],
orientation='h',
enable_events=True,
disable_number_display=True,
size=(28, 15),
key='pwdlength'),
sg.Text(pdict['pwdlength'], key='-PWDLEN-')
]
config_count = [
sg.Text("生成个数: "),
sg.Slider(range=(1, 100),
default_value=pdict['pwdCount'],
orientation='h',
enable_events=True,
disable_number_display=True,
size=(28, 15),
key='pwdCount'),
sg.Text(pdict['pwdCount'], key='-count-')
]
result_option_list = [sg.Listbox(
values=pwds, enable_events=True, key='-listpwd-', size=(50, 15))]
propmsg = [sg.Column(
[[sg.Text(text="点击单条密码,可自动复制", text_color='white', k='-PropMsg-')]], justification='center')]
copyAll = [
sg.Column([[sg.Button("复制所有密码", k='-COPYAll-', enable_events=True)]], justification='center')]
layout = [[
sg.Frame("参数设置",
[config_option, pwd_length_option, config_count, btn_column],
size=(450, 200))
],
[sg.Frame("执行结果", [propmsg, result_option_list, copyAll], size=(450, 415))]]
window = sg.Window("随机密码生成器", layout=layout, **optional)
while True:
event, values = window.read() # type: ignore
if event == sg.WIN_CLOSED:
break
if event == 'pwdCount':
window['-count-'].update(value=str(int(values['pwdCount'])))
if event == 'pwdlength':
window['-PWDLEN-'].update(value=str(int(values['pwdlength'])))
if event == 'sym':
window['spclistr'].update(disabled=not values['sym'])
if event in [
'sym', 'numbers', 'lowers', 'uppers', 'pwdlength', 'pwdCount',
'spclistr', '-regeneration-'
]:
pwds = batchPwd(values)
window['-listpwd-'].update(values=pwds)
if event == '-listpwd-':
sec_str = values['-listpwd-'][0][1]
window['-PropMsg-'].update(value=f"密码: {sec_str} 已经复制到剪切板")
pc.copy(sec_str)
if event == '-COPYAll-':
all_seclist = "\n".join([i[1] for i in pwds])
pc.copy(all_seclist)
window['-PropMsg-'].update(value=f"所有密码已经复制到剪切板")
window.close()
if __name__ == "__main__":
main()