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进行解析

目录

校验数据类型python python校验文件完整性_加载

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