马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 233倔强不秃 于 2020-2-12 16:06 编辑
一、引言:
本题来自python课后习题014的动动手动动手,题目如下:
0. 请写一个密码安全性检查的代码代码:check.py
# 密码安全性检查代码
#
# 低级密码要求:
# 1. 密码由单纯的数字或字母组成
# 2. 密码长度小于等于8位
#
# 中级密码要求
# 1. 密码必须由数字、字母或特殊字符(仅限:~!@#$%^&*()_=-/,.?<>;:[]{}|\)任意两种组合
# 2. 密码长度不能低于8位
#
# 高级密码要求:
# 1. 密码必须由数字、字母及特殊字符(仅限:~!@#$%^&*()_=-/,.?<>;:[]{}|\)三种组合
# 2. 密码只能由字母开头
# 3. 密码长度不能低于16位
二、分析:
1.检测为低级时:用字符串的BIF,isdigit()和isalpha() 检测是否全为数字或者字母。
2.将数字、字母、特殊符号分别存为三个字符串或者列表,用for循环和in判断其组成
3.程序主体还是用if...elif...else
三、源代码:
code = input('请输入进行安全性检查的密码:')
low = code.isalpha() or code.isdigit() #是否全是数字或字母
size = len(code) #长度
num = '123456790'
s = '~#$%^&*()_=-/,.?<>;:[]{}|\!@'
al = [ chr(i) for i in range(97,123)]#列表推导式
try:
#判断密码中是否有数字,若有则返回true
num_flag = 0
for i in code:
if i in num:
num_flag = 1
break
#判断密码中是否有字母,若有则返回true
code = code.lower()#全部转化为小写
a_flag = 0
for i in code:
if i in al:
a_flag = 1
break
#判断第一个字符是否是字母
f_flag = code[0] in al
#判断密码中是否有符号,若有则返回true
s_flag = 0
for i in code:
if i in s:
s_flag = 1
break
#判断是否有其中两种
mid = (num_flag and a_flag)or(num_flag and s_flag)or(a_flag and s_flag)
#判断是否三种都有
high = num_flag and a_flag and s_flag
def talk(): #打印提示
print('请按以下方法提升您的密码安全级别:')
print('\t1.密码必须由数字、字母及特殊字符三种组合')
print('\t2.密码只能由字母开头')
print('\t3.密码长度不能低于16位')
if size<=8 or low: #低
print('您的密码安全级别评定为:低')
talk()
elif (16>size>=8) or (mid and not high) :
print('您的密码安全级别评定为:中')
talk()
elif(size>=16) and high and f_flag:
print('您的密码安全级别评定为:高')
print('请继续保持!')
else:
print('请检查您输入的密码是否符合要求!')
print('原因如下:')
print('1.输入为空')
print('2.存在非法字符')
except:
print('检测到输入的密码为空!')
代码解释:
1.获取26个字母组成的list时,用了chr()函数,将ASCII码转换为对应字符。
2.当输入为空白时,f_flag = code[0] in al这个地方将会出错,因为code[0]不存在。所以用了异常处理try-except语句,虽然except后面什么也没有这种写法很不推荐,但是在这个程序中应该只会报这一种错,这样写应该没有问题。
3.还写了一个打印提示的函数talk。
4.用了lower()函数将字符串中的字母变为小写。
5.判断了字符串中是否包含有数字,字母或者特殊字符之后,将if后面的条件写在了外面,if里面直接写结果就行。
四、不足之处:
先看一下标准答案:symbols = r'''`!@#$%^&*()_+-=/*{}[]\|'";:/?,.<>'''
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
nums = '0123456789'
passwd = input('请输入需要检查的密码组合:')
# 判断长度
length = len(passwd)
while (passwd.isspace() or length == 0) :
passwd = input("您输入的密码为空(或空格),请重新输入:")
length = len(passwd)
if length <= 8:
flag_len = 1
elif 8 < length < 16:
flag_len = 2
else:
flag_len = 3
flag_con = 0
# 判断是否包含特殊字符
for each in passwd:
if each in symbols:
flag_con += 1
break
# 判断是否包含字母
for each in passwd:
if each in chars:
flag_con += 1
break
# 判断是否包含数字
for each in passwd:
if each in nums:
flag_con += 1
break
# 打印结果
while 1 :
print("您的密码安全级别评定为:", end='')
if flag_len == 1 or flag_con == 1 :
print("低")
elif flag_len == 3 and flag_con == 3 and (passwd[0] in chars):
print("高")
print("请继续保持")
break
else:
print("中")
print("请按以下方式提升您的密码安全级别:\n\
\t1. 密码必须由数字、字母及特殊字符三种组合\n\
\t2. 密码只能由字母开头\n\
\t3. 密码长度不能低于16位")
break
不得不说,姜还是老的辣。小甲鱼的写法中间有很多值得借鉴和学习的地方:
1. 直接用isspace()函数判断输入是否为空,就不用费事了。
2.将等级判断问题简化为:长度和复杂度,而更巧妙的是,我们都知道标签法设置flag,看到flag的值不是1或0还是第一次。小甲鱼将flag的值直接对应了等级,分别为1,2,3;
3.设置等级判断的顺序为低,高,中,这样中等级就省去了判断,而且还避免了中等级和高等级判断时容易犯的错。
3.while1的巧妙用法:将打印提示写在最后,如果不是高等级,就要执行打印提示,高等级直接break。这样设置很巧妙,减少了代码量,而我还设了函数去打印。。。
五、总结:
总结好的写法和好的思路,多实践将优点吸收。 |