我的Python成长之路---第一天---Python基础(作业1:登录验证)---2015年12月26日(*)

作业一:编写登录接口

  1. 输入用户名密码
  2. 认证成功系那是欢迎信息
  3. 输错三次后锁定

思路:

    1、参考模型,这个作业我参考了linux的登录认证流程以及结合网上银行支付宝等锁定规则

        1)认证流程参考的是Linux的登录:当你输入完用户名密码后再验证用户名是否存在用户是否被锁定,然后在验证密码是否正确,如果验证不过去只会告诉你验证失败,而不告诉你到底是用户名错误还是密码错误,增加了暴力破解的难度。如下图所示

        

        2)关于输入错误次数的计数和锁定,我参考的是银行和支付宝的做法,也就是只关心你输错了多少次,不关心输对了多少次,也就是说输错了两次,第三次输对了,前面的计数不清零,也就是你今天输入了1000次输对了997次,只输错了3次,那对不起,依然要锁定。而且输入错误的3次不一定要连续。只要三次输入错误三次就锁定。

    2、关于计数和状态的保存我考虑还是通过文件来持久化保存,每次输入错误次数的累加和锁定都保存到文件中,这样虽然增加了文件的操作,但是保证了程序的可靠性,这样程序退出,计数依然有效。用来保存用户信息的文件结构如下所示

         

流程图:

    设计思路有了,那么接下来就要把我们的思路和设计通过流程图的方式实现出来:流程图如下所示

 代码实现:

  1 #!/usr/bin/env python3
  2 # coding:utf-8
  3 '''
  4 Created on: 2015年12月29日
  5 
  6 @author: 张晓宇
  7 
  8 Email: 61411916@qq.com
  9 
 10 Version: 1.0
 11 
 12 Description: 输入用户名密码,认证成功显示欢迎信息,认证失败,输错三次后锁定
 13 
 14 Help:
 15 '''
 16 import os
 17 # 定义用户信息写入函数,用于把用户信息写回文件
 18 def write_to_account_file(accounts, account_file_path):
 19     account_file = open(account_file_path, 'w')
 20     for key,val in accounts.items():
 21         line = []
 22         line.append(key)
 23         line.extend(val)
 24         print(' '.join(line))
 25         account_file.write(' '.join(line) + '
')
 26     account_file.close()
 27 
 28 if __name__ == '__main__':
 29 
 30     '''
 31     @parameters:
 32         account_file_path: 账户文件
 33         password_col_num: 账户文件中密码所在的列(从0开始)
 34         status_col_num: 账户文件中账户状态所在的列(从0开始)
 35         error_count_num: 账户文件中输入错误次数所在的列(从0开始)
 36         app_info: 系统信息,用于启动应用后的输出
 37         welcome_msg: 用户成功登录系统后的信息
 38     '''
 39     account_file_path = 'account.db'
 40     password_col_num = 1
 41     status_col_num = 2
 42     error_count_num = 3
 43     app_info = '''
 44 +-----------------------------------+
 45 | Welcome to 65brother system       |
 46 | Version: 1.0                      |
 47 | Author: zhangxiaoyu               |
 48 +-----------------------------------+
 49 '''
 50     welcome_msg = 'Welcome %s, authentication is successful!'
 51     # 判断账户文件是否存在
 52     if os.path.exists(account_file_path):
 53         account_file = open(account_file_path, 'r')
 54     else:
 55         print('Error: Account file "account.db" is not exit, please check!')
 56         exit(1)
 57 
 58     # 读账户文件
 59     accounts = {}
 60     for line in account_file.readlines():
 61         account = line.strip().split()
 62         accounts[account[0]] = account[1:]
 63     account_file.close()
 64 
 65     flag = True
 66     while flag:
 67         print(app_info)
 68         # 输入用户名
 69         username = input('Username(Enter quit to exit): ').strip()
 70         # 判断是否输入的是否为quit
 71         if username == 'quit':
 72             # 是则退出循环,程序结束
 73             break
 74         password = input('Password: ').strip()
 75         # 判断用户名是否存在
 76         if username not in accounts:
 77             # 不存在提示错误信息并退出当前循环让用户重新输入
 78             print('Error: Username or Password it is error!')
 79             continue
 80         # 判断用户是否被锁定
 81         if accounts[username][status_col_num - 1] == 'lock':
 82             # 如果被锁定退出当前循环让用重新如输入
 83             print('Error: Account is locked. Please contact the administrator!')
 84             continue
 85         # 判断用户密码是否正确
 86         if password == accounts[username][password_col_num - 1]:
 87             # 正确显示欢迎信息
 88             print(welcome_msg %username)
 89             break
 90         else:
 91             # 不正确
 92             # 提示用户名或密码错误
 93             print('Error: Username or Password it is error!')
 94             # 输入错误次数加1
 95             accounts[username][error_count_num - 1] = str(int(accounts[username][error_count_num - 1]) + 1)
 96             # 判断是否已经达到3次
 97             if int(accounts[username][error_count_num - 1]) == 3:
 98                 # 如果输入错误达到3次
 99                 # 提示账户将被锁定
100                 print("Error: This account will be locked, Please contact the administrator! System will be exit!")
101                 # 将用户状态改为lock并写入文件
102                 accounts[username][status_col_num - 1] = 'lock'
103                 write_to_account_file(accounts, account_file_path)
104                 break
105             write_to_account_file(accounts, account_file_path)

 代码说明:

     1、这里用了两个今天课程没有讲的内容:字典和函数,将用户信息以字典的方式保存是出于判断用户名是否存在的考虑,读文件的时候直接将用户名作为字典的一个key,其他的信息作为字典的value与key一一对应,这样在判断用户名是否存在只需要通过in这个成员运算符进行判断就可以了

     2、代码的第61和62两行代码完成的就是将文件变成字典的过程

1 account = line.strip().split()   # 先把文件的每一行通过split方法将以空格分隔的用户信息转换成列表
2 accounts[account[0]] = account[1:]   # 然后把列表的的一个元素作为字典的key,剩下的转换成为value,完成列表到字典的转换

      转换成字典的过程大致的过程是这样的,如下图所示

原文地址:https://www.cnblogs.com/zhangxiaxuan/p/5089437.html