1. 开发环境
编程语言:Python3.7.4
IDE: VSCodium
操作系统:Windows 10 专业版
2. 前言
作为一名测试工程师在测试工作中经常需要搜集测试数据,涉及修改密码,注册等操作的时候总是一个密码想半天,为了解决这个问题干脆用Python手动写一个密码生成器。
当然网络上也有现成的密码生成器例如LINUX系统下的mkpasswd(系统自带)、pwgen(需要安装)等。
3. 开始码代码
-
需要了解的知识点
random 模块
密码构成:数字,大写字母,小写字母,特殊字符, 通常规则要求8-20位
-
设计思路
将大小写字母(a-zA-Z)数字(0-9)特殊字符组成一个字符串,然后用random函数随机抽取一部分内容返回
3.1 初步代码设计
# _*_ coding:utf-8 _*_
'''
@File : password_01.py
@TIME : 2019/09/27 13:32:36
@Autho : ningbing
@Phone : 15136220360
@Version : V1.0
@Email : 823825804@qq.com
@Desc : 密码生成器设计,将大小写字母(a-zA-Z)数字(0-9)特殊字符组成一个字符串,然后用random函数随机抽取一部分内容返回
'''
import string
from random import sample
def password_01(num):
# 获取所有的数字
num_str = string.digits
# 获取所有的消息字母
lower_str = string.ascii_lowercase
# 获取所有的大写字母
upper_str = string.ascii_uppercase
# 特殊字符
spe_str = '_@#!,.;:-=+\\/?'
# 返回随机密码
return ''.join(sample(num_str + lower_str + upper_str + spe_str, num))
执行函数50次查看执行结果:
-
代码解析
- 首先引入string、random模块
string模块中内置函数: digits, ascii_lowercase, ascii_upper。分别可以获取数字,小写字母,大写字母
- random模块内置函数: sample 可以从目标列表或者字符串中随机获取指定数目的字符生成一个数组
最后返回即可
-
总结
上面的代码没有控制密码复杂度,随机性太强有可能会出现生成的密码都是数字或者纯字母的情况。因此需要改进。
3.2 改进升级
-
设计思路
新增参数level和length, level为密码复杂度(1-4) length 为密码长度
新增函数CutLength, 根据level和length 将密码长度分割为一个数组数组长度为:level, 数组个数字之和为length。
例如:level=3 , length=10 输出: [4, 3, 3],
-
代码如下
# _*_ coding:utf-8 _*_ ''' @File : password_02.py @TIME : 2019/10/07 21:00:55 @Autho : ningbing @Phone : 15136220360 @Version : V1.0 @Email : 823825804@qq.com @Desc : 密码生成器改造 ''' import string from random import randint, choices, shuffle, sample def CutLength(level, length): # 剪切密码长度,根据密码等级将密码长度剪切 # 例如:输入:level = 3, length = 10。 输出 [3, 4, 3] res_arr = [] for i in range(level, 1, -1): res_arr.append(randint(1, length - sum(res_arr) - i + 1)) res_arr.append(length - sum(res_arr)) shuffle(res_arr) return res_arr def markpassword(dict, arr): # 获取密码数组,根据输入的密码字典和密码长度数组,随机获取密码值 res = [] for i in range(len(arr)): res += choices(dict[i], k=arr[i]) return res # 密码生成器主函数 def passwordgent(level, length): # 获取密码长度分布数组 arr = CutLength(level, length) # 获取所有数字(0-9) p_digits = string.digits # 获取所有小写字母(a-z) p_lowercase = string.ascii_lowercase # 获取所有大写字母(A-Z) p_uppercase = string.ascii_uppercase # 获取所有特殊字符 p_strt = '_@#!,.;:-=+\\/?' # 组装成数组字典 passdict = [p_digits, p_lowercase, p_uppercase, p_strt] res = [] # 判断level等级,如果level等级为1,则只在前三项中提取,避免密码都是特殊字符的情况 res = markpassword( sample(passdict[:-1] if level == 1 else passdict, level), arr) # 检查密码首位是否为特殊字符 while True: # 如果密码数组首位是特殊字符则重新排序 if res[0] in p_strt: shuffle(res) else: break # 返回密码,join函数将数组转为字符串 return ''.join(res)
测试结果