本文已参与「新人创作礼」活动,一起开启掘金创作之路。
需求
最近用控制台模拟了一个简单版本的注册登陆案例,用户信息保存在了文件db.txt中,使用文件操作对数据进行查找修改等操作。
以下是项目需求:
用户的信息需要保存在文件db.txt中
菜单:
供用户选择是注册还是登陆,还是其他项目
注册:
由用户输入用户名和密码
如果用户已经存在返回“用户已存在”
密码必须由字母和数字组成,长度不得小于8位
密码需要输入两次,并且判断密码是否相等,如果不相等注册失败
用户的密码需要进行加密之后处理
注册成功的话需要将用户信息写入db.txt中
登陆:
由用户输入用户名和密码
用户名不存在时返回“用户不存在”
用户名存在,密码错误时返回“密码错误”
登陆成功时返回“欢迎登陆成功!”
装饰器:
将验证登陆的过程写到装饰器中,因为有多个函数都需要在登陆之后才可以使用,这样可以提高代码复用率
其中文件的用户信息的格式如下: 用户名:散列值
lisi:7bdebfde48122cc446887230979fdaf9
wangwu:ac10d1cbe0ea30a8c00f1dc13ff0232f
zhangsan:acf7faf07d5038a373ba0dd392150bdf
主程序
主程序中主要是执行任务,涉及到的所有的功能都被封装到其他模块中,模块我通过register_and_login包组织在了一起,所以在需要用到的函数都得通过包导入对应的模块里的函数。
from register_and_login.db.select_all_from_db import select_all_from_db
from register_and_login.userinfo.register import register
from register_and_login.userinfo.login import login
from register_and_login.yule.yule import xizao, xijiao, anmo, menu
# 这个是用来控制登陆是否成功的标志位,登陆函数执行完之后的返回值用此变量接收,再对其他功能性函数通过参数传递进去。
flag_login = False
if __name__ == '__main__':
while True:
list1 = select_all_from_db("db.txt")
user_select = menu()
if user_select == "1":
register(list1)
elif user_select == "2":
flag_login = login(list1)
elif user_select =="3":
xijiao(flag_login)
elif user_select =="4":
xizao(flag_login)
elif user_select == "5":
anmo(flag_login)
else:
print("您输入的有误,请重新输入\n\n")
查询数据
这一步主要是向数据库查询出所有用户信息,然后将用户的信息构建成字典,并将所有用户信息添加到列表中并返回这样主程序在调用此函数的时候就可以接收到所有用户信息,只不过用户的信息在大型项目中是用数据库来保存,本案例中使用的是文件的方式。
def select_all_from_db(filename):
list1 = [] # 存储用户的信息
# 读取所有用户信息
with open(filename, "r") as read_file:
for line in read_file.readlines():
username_temp = line.strip().split(":")[0]
userpassword_temp = line.strip().split(":")[1]
dict1 = {"username": username_temp, "password": userpassword_temp}
list1.append(dict1)
return list1
注册账户
首先是由用户输入用户名,确保用户名未被注册过,然后再是由用户输入密码并且密码需要满足一定的要求。用户密码都没问题以后通过hashlib模块对用户密码加密,并且将用户的密码使用用户名进行加盐处理,这样不同的用户即使密码相同散列值也不同。最后将处理好的数据构造成对应的字符串格式写入文件中则代表完成注册功能。
import hashlib
def register(list1):
# 确保用户名未被注册过
while True:
user_name = input("请输入您的用户名")
flag1 = False
for dict2 in list1:
if dict2["username"] == user_name:
flag1 = True
if flag1:
print("用户已存在")
continue
else:
break
# 确保用户密码没有问题
while True:
user_password = input("请输入您的密码")
if len(user_password) < 8:
print("用户密码长度不得小于8")
continue
elif user_password.isdigit() or user_password.isalpha():
print("用户密码必须由字母和数字共同组成")
continue
elif user_password.isalnum():
print("密码合法!!!")
user_password2 = input("请再次输入您的密码")
if user_password != user_password2:
print("两次输入的密码不相等!!!")
continue
break
# 对用户密码进行加密处理
md5 = hashlib.md5()
md5.update(user_name.encode("utf-8"))
md5.update(user_password.encode("utf-8"))
user_password_md5 = md5.hexdigest()
print(user_password_md5)
# 将用户信息写入文件中
with open("db.txt", "a", encoding="utf-8") as write_file:
user_info = user_name + ":" + user_password_md5 + "\n"
write_file.write(user_info)
print(user_info)
print("注册成功!!!")
登陆系统
由用户输入用户名密码,用户的密码也是需要通过进行加密加盐之后和查询到的数据进行对比,如果没有问题则代表登陆成功,然后将登陆的结果返回。
import hashlib
def login(list1):
# 确保用户名存在
while True:
user_name = input("请输入登录名:")
flag1 = False
for dict2 in list1:
if dict2["username"] == user_name:
flag1 = True
if not flag1:
print("用户不存在")
continue
break
# 确保用户密码正确
while True:
user_password = input("请输入登陆密码:")
flag2 = False
md5 = hashlib.md5()
md5.update(user_name.encode("utf-8"))
md5.update(user_password.encode("utf-8"))
user_password_md5 = md5.hexdigest()
for dict3 in list1:
if dict3["username"] == user_name and user_password_md5 == dict3["password"]:
flag2 = True
if flag2:
print("登陆成功!!!")
return True
break
else:
print("密码输入错误,请重新输入!!!")
功能性函数
主要是增加了三个功能性函数函数内容比较简单,重点是这三个函数通过装饰器进行修饰之后可以要求必须在登陆之后才可以使用对应的功能,装饰器本身也通过参数接收来控制装饰器是否生效。
from register_and_login.userinfo.login_required import login_required
# 洗脚
@login_required(False)
def xijiao(flag_login):
print("欢迎洗脚!")
# 洗澡
@login_required(True)
def xizao(flag_login):
print("欢迎洗澡!")
# 按摩
@login_required(True)
def anmo(flag_login):
print("欢迎按摩!")
def menu():
print("欢迎来到彩虹洗脚城".center(40, "*"))
user_select = input("请输入您的选择序号:1注册,2登陆,3洗脚,4洗澡,5按摩")
return user_select
装饰器
这就是装饰器修饰了我们前面的功能函数,由于装饰器较为复杂,这里就不解释了,想要更多了解评论区交流。
def login_required(flag):
def outer(func):
def inner(flag_login):
if flag:
if flag_login:
func(flag_login)
else:
print("请先登陆")
else:
func(flag_login)
return inner
return outer