2、文件完整性校验(考虑大文件)
import hashlib
import random
import os
def get_md5(file_path):
size=os.path.getsize(file_path)
bytes_size=size*8
list_seek=[int(bytes_size/4),int(bytes_size/3),int(bytes_size/2)]
with open(file_path,"rb") as f:
m1=hashlib.md5()
for i in range(3):
f.seek(i,0)
data=f.read(7)
m1.update(data)
res=m1.hexdigest()
return res
# res=get_md5(r"E:\oldboy\classwork\reader_system\readme.txt")
# print(res) #a5d2db97ffa024feeb87b56b9410eca7
#先将文件改变前的md5存下来
res="a5d2db97ffa024feeb87b56b9410eca7"
def change_file(file_path):
size=os.path.getsize(file_path)
# print(size)
bytes_size=size*8
list_seek=[int(bytes_size/4),int(bytes_size/3),int(bytes_size/2)]
with open(file_path,"rb") as f:
m1=hashlib.md5()
for i in range(3):
f.seek(i,0)
data=f.read(7)
m1.update(data)
result=m1.hexdigest()
print(result)
if result == res:
print("文件完整")
else:
print("文件已损坏")
change_file(r"E:\oldboy\classwork\reader_system\readme.txt")
#1,3,4在项目中更改(小说阅读项目)
1、把登录与注册的密码都换成密文形式
3、注册功能改用json实现
4、项目的配置文件采用configparser进行解析
目录
import os,sys
dir=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(dir)
from core import src
if __name__ == '__main__':
src.run()
start.py
[db_path]
db_path=E:\oldboy\my_code\read_book\db\db_file
[book]
story_path=E:\oldboy\my_code\read_book\db\story_class.txt
book_dir=E:\oldboy\my_code\read_book\db\fictions
[log]
log_path=E:\oldboy\my_code\read_book\log\access.log
log_level=10
setting.cfg
import logging
import configparser
config=configparser.ConfigParser()
config.read(r'E:\oldboy\my_code\read_book\conf\setting.cfg',encoding="utf-8")
log_path=config.get("log","log_path")
log_level=config.get('log',"log_level")
log_level=int(log_level)
def log(log_type):
# 1、Logger:产生日志
loggger = logging.getLogger(log_type)
# 2、Filter:几乎不用
# 3、Handler:接收Logger传过来的日志,进行日志格式化,可以打印到屏幕,也可以打印到文件
sh = logging.StreamHandler() # 打印到终端
fh = logging.FileHandler(log_path, encoding="utf-8") # 打印到文件,文件名,或文件的绝对路径,可以指定字符编码
# 4、Formatter:指定日志格式
formatter1 = logging.Formatter(
fmt="%(asctime)s - %(name)s - %(levelname)s - %(module)s - %(message)s",
datefmt="%Y-%m-%d %X"
)
# 5、为Handler绑定日志格式
sh.setFormatter(formatter1)
fh.setFormatter(formatter1)
# 6、为logger绑定handler
loggger.addHandler(sh)
loggger.addHandler(fh)
# 7、设置日志级别,可以在第一步log1设置,也可以在第三步sh、fh这两个handler设置
# logger对象的日志级别应该<=handle的日志级别
# 方法一:通过级别的数字10,20,30,40,50
loggger.setLevel(log_level)
sh.setLevel(log_level)
fh.setLevel(log_level)
return loggger
log_handle.py
from db import db_handle
from lib import common
from core import log_handle
import time
import hashlib
data_info={
"name":None,
"data":None,
}
access_log=log_handle.log("access")
#用户注册
@common.logger
def register():
flag=True
while flag:
add_name=input("请输入注册的用户名:>>>").strip()
#如果用户输入b返回程序初始界面
if add_name == "b":
break
#加载用户信息,查看库中是否已存在注册的用户
user_data=db_handle.load_data(add_name)
if user_data:
print("输入的用户名,已被注册,请重新输入")
continue
add_passwd=input("请输入密码:>>>").strip()
re_add_passwd=input("请再次输入密码").strip()
if add_passwd == re_add_passwd:
m1=hashlib.md5()
m1.update(add_passwd.encode("utf-8"))
data={"name":add_name,"passwd":m1.hexdigest(),"balance":0}
now_time = time.strftime("%Y-%m-%d %H:%M:%S")
db_handle.dump_data(add_name,data)
log_data = "{} 用户[{}]注册成功".format(now_time, add_name)
print("用户[{}]注册成功".format(add_name))
return log_data
else:
print("两次密码输入不一致,请重新输入")
#用户登录
def user_login():
flag = True
while flag:
inp_name=input("请输入用户名:>>>").strip()
user_data = db_handle.load_data(inp_name)
if user_data:
count=0
while count < 3:
inp_pwd=input("请输入密码:>>>").strip()
m1=hashlib.md5()
m1.update(inp_pwd.encode("utf-8"))
if user_data["passwd"] == m1.hexdigest():
data_info["name"]=inp_name
data_info["data"]=user_data
now_time=time.strftime("%Y-%m-%d %H:%M:%S")
# print("用户[{}]登录成功".format(inp_name))
access_log.info("{} 用户[{}]登录成功".format(now_time,inp_name))
flag=False
break
else:
print("密码输入错误,请重新输入")
else:
print("输错三次,退出程序")
exit()
else:
print("输入的用户名不存在,请重新输入。")
#充值功能
@common.auth
@common.logger
def rechange():
flag=True
while flag:
rechange_money=input("请输入充值金额:>>>").strip()
if rechange_money.isdigit():
rechange_money=int(rechange_money)
user_data=data_info["data"]
user_data["balance"] += rechange_money
now_time = time.strftime("%Y-%m-%d %H:%M:%S")
db_handle.dump_data(data_info["name"],user_data)
log_data = "{} 用户[{}]成功充值{}元".format(now_time,data_info["name"],rechange_money)
print("用户[{}]成功充值{}元".format(data_info["name"],rechange_money))
return log_data
else:
print("请输入数字。。。")
#阅读小说功能
@common.auth
@common.logger
def reads():
flag=True
while flag:
print('''
----------小说阅读程序主页面----------
0. 玄幻武侠
1. 都市爱情
2. 高效养猪36技
q. 退出
b. 返回上一层
--------------end---------------
''')
#加载小说类型以及书籍名称的字典
story_dic=db_handle.story_info()
chooice=input("请输入小说类型编号:>>>").strip()
if chooice == "b":
break
if chooice == "q":
logout()
if chooice in story_dic:
for i in story_dic[chooice]:
print("小说编号[{}],小说名称<{}>,小说价格[{}]".format(i,story_dic[chooice][i][0],story_dic[chooice][i][1]))
while flag:
chooice1=input("请输入选择的小说编号:b返回上一层,q退出>>>").strip()
book_name=story_dic[chooice][chooice1][0]
book_price=int(story_dic[chooice][chooice1][1])
if chooice1 == "b":
break
if chooice1 == "q":
logout()
if chooice1 in story_dic[chooice]:
chooice2=input("是否确认购买:Y/N,y/n").strip()
if chooice2 == "y" or chooice2 == "Y":
#查看余额是否够买书
#加载用户信息
user_data=data_info["data"]
if user_data["balance"] < book_price:
print("尊敬的用户,您的余额不足以购买此书。。")
break
user_data["balance"]-=book_price
now_time = time.strftime("%Y-%m-%d %H:%M:%S")
db_handle.dump_data(data_info["name"],user_data)
print("购买成功,自动显示书籍信息~")
book_data=db_handle.read_book_info(book_name)
log_data = "{} 用户[{}]成功购买小说,花费{}元".format(now_time, data_info["name"], book_price)
db_handle.dump_log(log_data)
print('''
----------{}小说内容----------
{}
--------------end-------------
'''.format(book_name,book_data))
break
elif chooice2 == "n" or chooice2 == "N":
break
else:
print("请输入Y/N,y/n")
else:
print("输入的小说类型编号不存在,请重新输入。")
#退出程序
def logout():
chooice=input("确认退出Y/N,y/n:>>>").strip()
if chooice == "Y" or chooice == "y":
now_time = time.strftime("%Y-%m-%d %H:%M:%S")
if data_info["name"]:
log_data = "{} 用户[{}]退出登录".format(now_time, data_info["name"])
db_handle.dump_log(log_data)
exit()
else:
log_data = "{} 游客用户退出程序".format(now_time)
db_handle.dump_log(log_data)
exit()
elif chooice == "N" or chooice == "n":
pass
else:
print("请输入Y/N,y/n")
func_dic={
"0":register,
"1":user_login,
"2":rechange,
"3":reads,
"4":logout,
}
#主运行程序
def run():
flag=True
while flag:
print('''
----------小说阅读程序----------
0. 注册
1. 登录
2. 充值
3. 阅读小说
4. 退出
--------------end---------------
''')
chooice=input("请输入功能id:>>>").strip()
if chooice in func_dic:
func_dic[chooice]()
print("")
else:
print("输入的功能id不存在。")
src.py
{"name": "egon", "passwd": "202cb962ac59075b964b07152d234b70", "balance": 1200}
egon.json
import os
import json
import configparser
config=configparser.ConfigParser()
config.read(r'E:\oldboy\my_code\read_book\conf\setting.cfg',encoding="utf-8")
db_path=config.get('db_path',"db_path")
story_path=config.get("book","story_path")
book_dir=config.get("book","book_dir")
log_path=config.get("log","log_path")
#读取用户信息
def load_data(user_name):
#判断用户文件是否存在,以及返回信息
user_file="{}.json".format(user_name)
user_file_path=os.path.join(db_path,user_file)
if os.path.isfile(user_file_path):
with open(user_file_path,"r",encoding="utf-8") as f:
user_data=json.load(f)
return user_data
#更新用户信息
def dump_data(user_name,user_data):
user_file = "{}.json".format(user_name)
user_file_path = os.path.join(db_path, user_file)
with open(user_file_path, "w", encoding="utf-8") as f:
json.dump(user_data,f)
#加载书籍信息字典
def story_info():
with open(story_path,"r",encoding="utf-8") as f:
story_dic=f.read()
return eval(story_dic)
#上传时更新点和书籍目录
def up_book():
pass
#购买成功,打印书籍信息
def read_book_info(book_name):
book_path=os.path.join(book_dir,book_name)
with open(book_path,"r",encoding="utf-8") as f:
book_data=f.read()
return book_data
#将日志信息打印到日志文件
def dump_log(data):
with open(log_path,"a",encoding="utf-8") as f:
f.write("{}\n".format(data))
db_handle.py
{"0":{"0":["倚天屠狗记.txt",85],"1":["沙雕英雄转.txt",90]},"1":{"0":["令人羞耻的爱.txt",66],"1":["二狗的妻子与大草原的故事.txt",75]},"2":{"0":["高效养猪36技-上.txt",35],"1":["高效养猪36技-下.txt",55]},}
story_class.txt
from db import db_handle
#验证用户是否登录装饰器
def auth(func):
from core import src
def inner(*args,**kwargs):
if src.data_info["name"]:
res=func(*args,**kwargs)
return res
else:
print("还没有登录,请先登录。。。")
src.user_login()
res = func(*args, **kwargs)
return res
return inner
#日志记录装饰器
def logger(func):
def inner(*args, **kwargs):
res = func(*args, **kwargs)
db_handle.dump_log(res)
return inner
common.py