常用模块讲解(三)

常用模块讲解(三)

hashlib加密模块

  1. 什么是加密?

    就是将明文(人能看得懂的)数据通过一些手段变成密文数据(人看不懂的),密文数据的表现形式一般都是一串没有规则的字符串。

  2. 加密算法

    加密算法有很多种,加密算法就是将明文变密文的内部规则,加密算法的难易程度可以根据产生密文的长短来判断,越长意味着算法越复杂。

  3. 加密使用场景

    涉及到隐私数据的时候,就会考虑加密,最为常见的就是对用户的密码加密,防止密码泄露。用户输入的还是明文但是到了程序里面之后会采用相同的加密算法变成密文,之后拿着密文与跟数据库里面的密文比对如果一致就是密码正确不一致就是错误。

  4. md5算法

    md5算法是最为常见的加密算法,可以满足一般的业务需求了。

import hashlib
md5 = hashlib.md5()  # 指定算法
# 将明文数据传递给算法对象
md5.update(b'hello')  # 只能接收bytes类型
res = md5.hexdigest()  # 获取加密之后的密文
print(res)  # 5d41402abc4b2a76b9719d911017c59

在传入数据的时候,只要内容一致,那么算法的结果肯定一致

md5 = hashlib.md5()
# md5.update(b'asd')
# md5.update(b'hello')
# md5.update(b'oscar')
# print(md5.hexdigest())  # 7e2574e7470e97d6221d6159c348c68c
md5.update(b'asdhellooscar')
print(md5.hexdigest())  # 7e2574e7470e97d6221d6159c348c68c
  1. 加密之后的结果是无法直接反解密的

    所谓的反解密就是靠反复的猜,也就是暴力解密,网上有这些解密的操作,本质就是自己写了很多不同的的数据,然后进行加密,之后把数据和对应的密文存储在数据库中,我们去解密的时候就是进行一一比对。

  2. 加盐处理

# 增加破解难度
md5 = hashlib.md5()
md5.update('你干嘛'.encode('utf8'))  # 加盐处理,就是添加一些额外的干扰项
md5.update(b'oscar')
print(md5.hexdigest())  # 4ce3e71a6a31b22e504b3cc8acde95d6
# 还可以动态加盐,就是干扰项变成动态的,比如时间等等

logging模块

  1. 日志等级

import logging
# 日志按照重要程度分为五个级别:默认只有达到warning警告级别及以上才会记录日志
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')
  1. 基本使用

# 当程序运行完之后你会发现自动创建了一个a11.log文件,里面记录了我们的一些操作
file_logging = logging.FileHandler(filename='a11.log',mode='a',encoding='utf8')
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
      datefmt='%Y-%m-%d %H:%M:%S %p',handlers = [file_logging],level = logging.ERROR)
logging.error('记录一下')

购物车

	# 项目功能
  	1.用户注册
    2.用户登录
    3.添加购物车
    4.结算购物车
  # 项目说明
  	用户数据采用json格式存储到文件目录db下 一个用户一个单独的文件
    	数据格式 {"name":"jason","pwd":123} 
      # ps:文件名可以直接用用户名便于校验
    用户注册时给每个用户添加两个默认的键值对(账户余额 购物车)
    	{"balance":15000,"shop_car":{}}
    添加购物车功能 商品列表可以自定义或者采用下列格式
    	good_list = [
        		['挂壁面',3]
        		['印度飞饼', 22]
            ['极品木瓜', 666], 
            ['土耳其土豆', 999],  
            ['伊拉克拌面', 1000],  
            ['董卓戏张飞公仔', 2000],  
            ['开天辟地', 10000] 
        ]
      用户可以反复添加商品,在购物车中记录数量
      		{'极品木瓜':[个数,单价]}
    结算购物车
    	获取用户购物车中所有的商品计算总价并结算即可
  # 思考:针对添加购物车和结算只有登录的用户才可以执行如何实现
import os
import json
res = os.path.dirname(__file__)  # 动态获取路径
res_db = os.path.join(res, r'db')  # 拼接路径
if not os.path.exists(res_db):  # 判断路径是否存在
    os.mkdir(r'db')  # 不存在则创建文件

name_dict = {}

def func_all():
    while True:
        print('''
        1.注册
        2.登录
        3.添加购物车
        4.清空购物车
        5.退出
        ''')
        chooes = input('你想干嘛>>:').strip()
        if chooes == '1':
            register()
        elif chooes == '2':
            login()
        elif chooes == '3':
            apptend_car()
        elif chooes == '4':
            clear_car()
        elif chooes == '5':
            return
        else:
            print('暂未开放')

is_login = {'username': None}  # 定义一个全局变量,用于验证用户是否登录

def outer(func_name):  # 验证用户是否登录的装饰器
    def inner(*args, **kwargs):
        if is_login.get('username'):  # 如果is_login.get('username')不是空值,证明登录成功
            func_name(*args, **kwargs)
        else:
            print('请先登录')
            login()  # 否则先登录
    return inner

def register():
    username = input('名字>>:').strip()
    passward = input('密码>>:').strip()
    name_dict = {'username': username,
                 'password': passward,
                 'balance': 15000,
                 'shop_car': {}}
    res_db_username = os.path.join(res_db, fr'{username}.json')  # 拼接路径
    if not os.path.exists(res_db_username):  # 判断路径是否存在,等于判断用户名是否存在
        with open(res_db_username,'w',encoding='utf8') as f:  #不存在使用文本操作的w模式进行创建并写入信息
            json.dump(name_dict,f)  # 序列化转为json格式
            print(f'用户{username}注册成功')
    else:
        print(f'用户{username}已存在')


def login():
    username = input('名字>>:').strip()
    passward = input('密码>>:').strip()
    res_db_username = os.path.join(res_db, fr'{username}.json')  # 拼接路径
    if not os.path.exists(res_db_username):  # 判断路径是否存在,等于判断用户名是否存在
        print('对不起用户名不存在或错误')
    else:
        with open(res_db_username,'r',encoding='utf8') as f:  # 如果存在,则使用只读模式打开文件
            login_dict = json.load(f)  # 反序列化,转为相对应的Python数据类型
        if login_dict['password'] == passward:  # 校验密码是否正确
            print('登录成功')
            is_login['username'] = username  # 如果登录成功,改变全局变量is_login的v值
        else:
            print('密码错误')

good_list = [
        	['挂壁面',3],
        	['印度飞饼', 22],
            ['极品木瓜', 666],
            ['土耳其土豆', 999],
            ['伊拉克拌面', 1000],
            ['董卓戏张飞公仔', 2000],
            ['仿真玩偶', 10000]
        ]
@outer  # 语法糖
def apptend_car():
    shop_car_dict = {}  # 定义一个临时字典
    while True:
        for a,b in enumerate(good_list,start=1):  # 利用枚举,列举出所有商品的信息和编号
            print('''商品编号:%s---商品名称:%s---商品单价:%s'''% (a,b[0],b[1]))
        chooes_buy = input('你想买啥,(y退出)>>:').strip()  # 获取用户的操作
        if chooes_buy == 'y':  # 输入y直接退出
            return
        if chooes_buy.isdigit():  # 如果不是y,判断是否是纯数字
            chooes_buy = int(chooes_buy)  # 转换类型,转为整型
            if chooes_buy in range(1,len(good_list) + 1):  # 判断用户输入的编号是否属于商品编号
                chooes_buy_name = good_list[chooes_buy - 1][0]  # 获取商品名称
                chooes_buy_pice = good_list[chooes_buy - 1][1]  # 获取商品单价
            buy_number = input('你想买多少份>>:').strip()  # 获取用户想要买的数量
            if buy_number.isdigit():  # 判断是否是纯数字
                buy_number = int(buy_number)  # 转换类型,转为整型
            if chooes_buy_name not in shop_car_dict.keys():  # 判断商品名称是否在临时字典的k值中
                shop_car_dict[chooes_buy_name] = [buy_number,chooes_buy_pice]  # 如果不在,就作为k值,v值是一个列表,列表中的元素是购买的数量和商品单价
            else:
                shop_car_dict[chooes_buy_name][0] += buy_number  # 如果商品名称是否在临时字典的k值中,那就取出v值,利用下标索引来修改购买的数量
        else:
            print('请输入正确的商品编号')
            continue
        # name_dict['shop_car'] = shop_car_dict
        res_db_username = os.path.join(res_db, '%s.json'% is_login.get('username'))  # 拼接路径,第二个参数就是已经登录的用户文件
        with open(res_db_username,'r',encoding='utf8') as f:  # 利用只读模式打开改文件
            car_dict = json.load(f)  # 反序列化,转为相对应的Python数据类型,并用变量名接收
        # car_dict['shop_car'] = shop_car_dict
        real_car_dict = car_dict['shop_car']  # 用一个变量名来接收取出来的car_dict['shop_car'],也就是购物车的字典
        for shop_name in shop_car_dict:  # for循环临时字典
            if shop_name in real_car_dict:  # 判断临时字典中的k值是否在购物车的字典
                real_car_dict[shop_name][0] += shop_car_dict[shop_name][0]  # 如果在,就把购物车的字典中该k值对应的v值中的商品个数加上临时字典中该k值对应的v值的中商品个数
            else:
                real_car_dict[shop_name] = shop_car_dict[shop_name]  # 如果不存在,添加新的键值对
        car_dict['shop_car'] = real_car_dict  # 把旧的购物车字典进行更新
        with open(res_db_username,'w',encoding='utf8') as f1:  # 利用只写模式打开文件
            json.dump(car_dict,f1,ensure_ascii=False)  # 序列化写入文件,第三个参数是显示json格式中的中文
@outer
def clear_car():
    sum_all = 0  # 定义一个变量
    res_db_username = os.path.join(res_db, '%s.json' % is_login.get('username'))  # 拼接路径,第二个参数就是已经登录的用户文件
    with open(res_db_username, 'r', encoding='utf8') as f:  # 利用只读模式打开改文件
        car_dict = json.load(f)  # 反序列化,转为相对应的Python数据类型,并用变量名接收
        car_dict_values = car_dict['shop_car'].values()  # 定义一个变量名来接收购物车字典的v值
    for a,b in car_dict_values:  # 解压赋值
        sum_all += a * b  # 算出总消费
    if sum_all < car_dict['balance']:  # 判断余额与总消费的的大小
        balance_money = car_dict['balance'] - sum_all  # 减去消费之后的余额
        car_dict['balance'] = balance_money  # 对余额进行更新
        car_dict['shop_car'] = {}  # 清空购物车
        with open(res_db_username, 'w', encoding='utf8') as f1:  # 利用只写模式打开文件
            json.dump(car_dict,f1)  # 序列化写入文件
        print(f'结算成功,你的余额为{balance_money}')
    else:
        print('你的余额不足')

func_all()  # 调用函数,开始执行

这里是IT小白陆禄绯,欢迎各位大佬的指点!!!

posted @ 2022-03-31 20:00  陆禄绯  阅读(68)  评论(0)    收藏  举报