hashlib加密模块

简介

  hashlib模块是一个提供了字符串加密功能的模块,包含MD5和SHA的加密算法。具体的加密支持有:
MD5,sha1,sha224,sha256, sha384, sha512, blake2b,blake2s,sha3_224, sha3_256,
sha3_384, sha3_512, shake_128, shake_256
该模块在用户登录认证方面应用广泛,对文本加密也很常见。文件和文件之间的校验。

基本调用

  基本步骤,加密算法使用方法都一样的。以MD5加密为例:
1.创建一个MD5加密对象
2.对字符串进行转换为byte后,进行算法加密
3.进行16进制的显示

代码演示:

  # 导入hashlib模块
import hashlib # 实例化一个MD5的加密对象
md5 = hashlib.md5()
# 调用MD5对象的update方法,进行字符串加密(这里要传入的是编码后字节)
md5.update('hello'.encode('utf8'))
# 返回一个仅包含16进制数字的字符串
ret = md5.hexdigest()
# 打印加密返回后的字符串
print(ret)
5d41402abc4b2a76b9719d911017c592

可以创建的加密算法有:md5,sha1, sha224, sha256, sha384, sha512

  # 实例化一个MD5加密对象
md5 = hashlib.md5()
# 实例化一个sha1加密对象
sha1 = hashlib.sha1()
# 实例化一个sha224加密对象
sha224 = hashlib.sha224()
# 实例化一个sha256加密对象
sha256 = hashlib.sha256()

如果数据量较大,可以分块多次调用update(),最后的计算结果都是一样的

  md5 = hashlib.md5()
md5.update('春游去'.encode('utf8'))
md5.update('动物园'.encode('utf8'))
res = md5.hexdigest()
print(res)
dbc49f26ce915c5f7a13bba1c21679f2 new_md5 = hashlib.md5()
new_md5.update('春游去动物园'.encode('utf8'))
new_res = md5.hexdigest()
print(new_res)
dbc49f26ce915c5f7a13bba1c21679f2

加盐处理

简介

  但是通常这样的密码就相当于一个固定的加密字符串,如果有的人专门写一个这样的字典,里面存储了各
种字符串组合及对应的MD5加密字符串,然后去暴力测试,这样也就有可能计算出我们真正的密码,所以,要
确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串
来实现,俗称“加盐”:

代码演示:

  # 没有加盐的字符串加密
new_md5 = hashlib.md5()
new_md5.update('how to use md5 in python hashlib?'.encode('utf8'))
print(new_md5.hexdigest()) # 加盐以后的字符串加密
new_md5 = hashlib.md5('我的梦想是冲出地球!'.encode('utf8')) # 加盐
new_md5.update('how to use md5 in python hashlib?'.encode('utf8'))
print(new_md5.hexdigest()) # 结果
# d26a53750bc40b38b65a520292f69306
# 52841008c37295e291f426bbabe56f15

动态加盐

  # 意义就是在加盐的地方使用一个变量比如,用户名
user = input('user>>: ')
pwd = input('pwd>>: ') md5 = hashlib.md5('{0}的梦想是去全世界各种地方逛逛'.format(user).encode('utf8'))
md5.update(pwd.encode('utf8')) # 更新密码
print(md5.hexdigest())

校验文件时,由于文件过大,计算MD5值的方法:

  def file_get_md5(file):
md5 = hashlib.md5()
with open(file, mode='rb') as fp: # 打开文件
for line in fp: # 循环,每次一行
md5.update(line) # 每次更新
return md5.hexdigest()

应用场景

  1.密码加密如何比对
用户输入的还是明文但是到了程序里面之后会采用相同的加密算法变成密文
之后拿着密文与跟数据库里面的密文比对如果一致就是密码正确不一致就是错误 2.文件内容一致性校验
作为软件的提供者 我们在提供安全软件的同时会对给该软件内容做加密处理得到一个该安全软件独有的密文
用户在下载软件之后也会对内容做相同的加密之后比对两次密文是否一致
如果是表示中途没有被修改 如果不是表示中途被修改过 可能存在病毒

logging模块

简介

  logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等;相比print,具备如下优点:

  1.可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
2.print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出;

基本使用

   日志按照重要程度分为五个级别:默认只有达到warning警告级别及以上才会记录日志
logging.debug('debug message') # 10
logging.info('info message') # 20
logging.warning('warning message') # 30
logging.error('error message') # 40
logging.critical('critical message') # 50 配置logging基本的设置,然后在控制台输出日志 import logging
logging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__) logger.info("Start print log")
logger.debug("Do something")
logger.warning("Something maybe fail.")
logger.info("Finish")

logging.basicConfig函数各参数

  filename:指定日志文件名;

  filemode:和file函数意义相同,指定日志文件的打开模式,'w'或者'a';

  format:指定输出的格式和内容,format可以输出很多有用的信息
参数:作用
%(levelno)s:打印日志级别的数值
%(levelname)s:打印日志级别的名称
%(pathname)s:打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s:打印当前执行程序名
%(funcName)s:打印日志的当前函数
%(lineno)d:打印日志的当前行号
%(asctime)s:打印日志的时间
%(thread)d:打印线程ID
%(threadName)s:打印线程名称
%(process)d:打印进程ID
%(message)s:打印日志信息 datefmt:指定时间格式,同time.strftime()(格式化时间); level:设置日志级别,默认为logging.WARNNING; stream:指定将日志的输出流,可以指定输出到sys.stderr,sys.stdout或者文件,默认输出到
sys.stderr,当stream和filename同时指定时,stream被忽略;

购物车项目

要求:

     项目功能
1.用户注册
2.用户登录
3.添加购物车
4.结算购物车
项目说明
用户数据采用json格式存储到文件目录db下 一个用户一个单独的文件
数据格式 {"name":"jason","pwd":123} '''密码必须加密后存储''' ps:文件名可以直接用用户名便于校验
用户注册时给每个用户添加两个默认的键值对(账户余额 购物车)
{"balance":15000,"shop_car":{}}
添加购物车功能 商品列表可以自定义或者采用下列格式
good_list = [
['挂壁面',3]
['印度飞饼', 22]
['极品木瓜', 666],
['土耳其土豆', 999],
['伊拉克拌面', 1000],
['董卓戏张飞公仔', 2000],
['仿真玩偶', 10000]
]
用户可以反复添加商品,在购物车中记录数量
{'极品木瓜':[个数,单价]}
结算购物车
获取用户购物车中所有的商品计算总价并结算即可

一.分析要求,搭框架

拿到项目的第一步是分析要求,然后搭建起简单的框架。将我们可能需要用到的函数提前先定义了,函数体用pass填入,再将函数

名放入字典中,方便之后使用和追加函数,然后将主要的运行代码写好,再来进行函数体代码的编写。

二.将函数的功能一个一个完善起来

判断db文件是否存在,如不存在则创建

  if not os.path.exists(data_path):
os.mkdir(data_path)

注册

首先我们要获取用户输入的用户名和密码,并且密码要二次验证。如果2次密码不一致,则提醒用户密码不一致。然后使用os.path.join方法来拼出存储用户信息的文件路径,因为我们是使用用户名作为文件名的,所以我们可以判断这个路径下有没有相同的文件,如果有,则提示用户账号已存在,没有则先将密码md5加密并且使用动态加盐处理然后初始化一条用户数据,存入文件中。

  #注册
def register():
# 获取用户名和密码
name = input('请输入你的用户名: ').strip()
pwd = input('请输入你的密码: ').strip()
pwd_again = input('再次确认密码: ').strip()
# 判断两次密码是否一致,不一致提醒用户
if pwd_again != pwd:
print('------两次密码不一致------')
return
# 使用os.path.join方法拼出存储用户信息的文件路径
user_file_path = os.path.join(data_path, f'{name}.json')
# 该用户文件存在,则提醒用户
if os.path.exists(user_file_path):
print('------用户已经存在------')
return
# 初始化用户数据
md5 = hashlib.md5()
md5.update(f'{name}用户的密码是{pwd}'.encode('utf8')) # 动态加盐
res = md5.hexdigest()
user_dict = {'name': name, 'pwd': res, 'balance': 15000, 'shop_car': {}}
# 将用户数据写入文件
open_file_write(user_file_path,user_dict)
print(f'------用户 {name} 注册成功------')

登入

先获取用户输入的用户名和密码,将用户名拼成的文件名在db目录中去查找,如果没有,则提示用户不存在,有就进行密码的比对。密码比对正确则登入成功。登入成功后将全局变量is_login字典中的name对应的值改为登入的用户名。

  #登入
def login():
# 获取用户名和密码
name = input('请输入你的用户名: ').strip()
pwd = input('请输入你的密码: ').strip()
# 使用os.path.join方法拼出存储用户信息的文件路径
user_file_path = os.path.join(data_path, f'{name}.json')
# 判断数据库中是否有这个用户的数据,没有则提示用户
if not os.path.exists(user_file_path):
print('------用户不存在------')
return
# 将数据从文件中转成原数据格式
user_dict = open_file_read(user_file_path)
# 判断用户输入的密码是否正确
md5 = hashlib.md5()
md5.update(f'{name}用户的密码是{pwd}'.encode('utf8'))
res = md5.hexdigest()
if res == user_dict['pwd']:
print('------登入成功------')
# 记录已登入的用户
is_login['name'] = name
else:
print('------账号或密码错误------')

添加购物车

先向用户展示商品信息,然后我们可以先定义一个临时的空的购物车,将用户选购的商品临时添加到临时购物车。获取用户输入的商品编号和数量,然后将对应的商品名,数量和单价添加到临时购物车,当用户输入exit时退出购物,并且将临时购物车中的数据更新到对应用户的数据文件中。

    #添加购物车
def add_shop_car():
good_list = [
['挂壁面', 3],
['印度飞饼', 22],
['极品木瓜', 666],
['土耳其土豆', 999],
['伊拉克拌面', 1000],
['董卓戏张飞公仔', 2000],
['仿真玩偶', 10000]
]
# 创建一个临时的购物车
shop_char = {}
while True:
# 循环打印出商品信息
for i, j in enumerate(good_list, start=0):
print(f'商品编号:{i} | 商品名:{j[0]} | 商品单价:{j[1]}')
# 获取用户输入的编号
chioce = input('请输入要购买的商品的编号,或输入exit退出购物: ').strip() # 判断用户是否想退出购物,如要退出,将购物车加入到对应的用户数据中去
if chioce == 'exit':
# 拼出对应用户的数据文件路径
user_file_path = os.path.join(data_path, '%s.json' % is_login.get('name'))
# 将用户数据读出来
user_dict = open_file_read(user_file_path)
# 判断用户原来的购物车中是否有东西,有就增加,没有就添加新的键值对
for name in shop_char.keys():
if name in user_dict['shop_car'].keys():
user_dict['shop_car'][name][0] += shop_char[name][0]
else:
user_dict['shop_car'][name] = shop_char[name]
# 将用户信息重写回文件
open_file_write(user_file_path,user_dict)
print('------添加成功------')
break # 如果用户输入的是商品编号,则准备开始添加
if int(chioce) in range(len(good_list)):
# 将商品名和单价分别取出来,放如两个变量
good_list_list = good_list[int(chioce)]
good_list_name = good_list_list[0]
good_list_money = good_list_list[1]
numb = int(input('请输入数量: ').strip())
if good_list_name in shop_char.keys():
# 购物车中已经有该商品,则添加数量
shop_char[good_list_name][0] += numb
else:
# 购物车没这个商品也就是第一次添加,则向零时购物车中新增键值对
shop_char[good_list_name] = [numb, good_list_money]
else:
print('------请输入数字编号------')

结算

先获取对应用户的余额,在计算购物车中的总价,如果总价大于余额,则提示用户余额不足,否则将余额减去总价,再将这些数据写回文件中。

  def pay():
#获取用户余额
user_file_path = os.path.join(data_path, '%s.json' % is_login.get('name'))
user_dict = open_file_read(user_file_path)
user_money = user_dict['balance']
need_money = 0
# 计算需要的金额
for i in user_dict['shop_car'].values():
need_money += i[0] * i[1]
#如果总计大于余额提示用户额不足,否则结算成功,购物车清空
if need_money > user_money:
print('------余额不足------')
else:
user_dict['shop_car'] = {}
user_dict['balance'] = user_money-need_money
open_file_write(user_file_path,user_dict)
print('------结算成功------')
print(f'---本次消费:{need_money},账户余额:{user_money-need_money}---')

验证装饰器

装饰器,判断再进行购物车添加和结算时先判断用户是否已登入

  def f1(func):
def f2(*args, **kwargs):
if is_login.get('name'):
res = func(*args, **kwargs)
return res
else:
print('------请先登入------')
login()
return f2

代码

import os
import json
import hashlib # 获取执行文件的路径
yun_path = os.path.dirname(__file__) # 使用os.path.join方法拼出db文件路径
data_path = os.path.join(yun_path, 'db') # 定义一个全局变量,记录已登入的用户名
is_login = {'name': None} # 判断db文件是否存在,如不存在则创建
if not os.path.exists(data_path):
os.mkdir(data_path) # 装饰器,判断再进行购物车添加和结算时先判断用户是否已登入
def f1(func):
def f2(*args, **kwargs):
if is_login.get('name'):
res = func(*args, **kwargs)
return res
else:
print('------请先登入------')
login()
return f2 def open_file_read(path):
with open(path) as f1:
user_dict = json.load(f1)
return user_dict def open_file_write(path,user_dict):
with open(path, 'w') as f1:
json.dump(user_dict, f1)
#注册
def register():
# 获取用户名和密码
name = input('请输入你的用户名: ').strip()
pwd = input('请输入你的密码: ').strip()
pwd_again = input('再次确认密码: ').strip()
# 判断两次密码是否一致,不一致提醒用户
if pwd_again != pwd:
print('------两次密码不一致------')
return
# 使用os.path.join方法拼出存储用户信息的文件路径
user_file_path = os.path.join(data_path, f'{name}.json')
# 该用户文件存在,则提醒用户
if os.path.exists(user_file_path):
print('------用户已经存在------')
return
# 初始化用户数据
md5 = hashlib.md5()
md5.update(f'{name}用户的密码是{pwd}'.encode('utf8')) # 动态加盐
res = md5.hexdigest()
user_dict = {'name': name, 'pwd': res, 'balance': 15000, 'shop_car': {}}
# 将用户数据写入文件
open_file_write(user_file_path,user_dict)
print(f'------用户 {name} 注册成功------') #登入
def login():
# 获取用户名和密码
name = input('请输入你的用户名: ').strip()
pwd = input('请输入你的密码: ').strip()
# 使用os.path.join方法拼出存储用户信息的文件路径
user_file_path = os.path.join(data_path, f'{name}.json')
# 判断数据库中是否有这个用户的数据,没有则提示用户
if not os.path.exists(user_file_path):
print('------用户不存在------')
return
# 将数据从文件中转成原数据格式
user_dict = open_file_read(user_file_path)
# 判断用户输入的密码是否正确
md5 = hashlib.md5()
md5.update(f'{name}用户的密码是{pwd}'.encode('utf8'))
res = md5.hexdigest()
if res == user_dict['pwd']:
print('------登入成功------')
# 记录已登入的用户
is_login['name'] = name
else:
print('------账号或密码错误------') @f1
def add_shop_car():
good_list = [
['挂壁面', 3],
['印度飞饼', 22],
['极品木瓜', 666],
['土耳其土豆', 999],
['伊拉克拌面', 1000],
['董卓戏张飞公仔', 2000],
['仿真玩偶', 10000]
]
# 创建一个临时的购物车
shop_char = {}
while True:
# 循环打印出商品信息
for i, j in enumerate(good_list, start=0):
print(f'商品编号:{i} | 商品名:{j[0]} | 商品单价:{j[1]}')
# 获取用户输入的编号
chioce = input('请输入要购买的商品的编号,或输入exit退出购物: ').strip() # 判断用户是否想退出购物,如要退出,将购物车加入到对应的用户数据中去
if chioce == 'exit':
# 拼出对应用户的数据文件路径
user_file_path = os.path.join(data_path, '%s.json' % is_login.get('name'))
# 将用户数据读出来
user_dict = open_file_read(user_file_path)
# 判断用户原来的购物车中是否有东西,有就增加,没有就添加新的键值对
for name in shop_char.keys():
if name in user_dict['shop_car'].keys():
user_dict['shop_car'][name][0] += shop_char[name][0]
else:
user_dict['shop_car'][name] = shop_char[name]
# 将用户信息重写回文件
open_file_write(user_file_path,user_dict)
print('------添加成功------')
break # 如果用户输入的是商品编号,则准备开始添加
if int(chioce) in range(len(good_list)):
# 将商品名和单价分别取出来,放如两个变量
good_list_list = good_list[int(chioce)]
good_list_name = good_list_list[0]
good_list_money = good_list_list[1]
numb = int(input('请输入数量: ').strip())
if good_list_name in shop_char.keys():
# 购物车中已经有该商品,则添加数量
shop_char[good_list_name][0] += numb
else:
# 购物车没这个商品也就是第一次添加,则向零时购物车中新增键值对
shop_char[good_list_name] = [numb, good_list_money]
else:
print('------请输入数字编号------') @f1
def pay():
#获取用户余额
user_file_path = os.path.join(data_path, '%s.json' % is_login.get('name'))
user_dict = open_file_read(user_file_path)
user_money = user_dict['balance']
need_money = 0
# 计算需要的金额
for i in user_dict['shop_car'].values():
need_money += i[0] * i[1]
#如果总计大于余额提示用户额不足,否则结算成功,购物车清空
if need_money > user_money:
print('------余额不足------')
else:
user_dict['shop_car'] = {}
user_dict['balance'] = user_money-need_money
open_file_write(user_file_path,user_dict)
print('------结算成功------')
print(f'---本次消费:{need_money},账户余额:{user_money-need_money}---') def login_out():
# 初始化,还原到未登入状态
is_login['name'] = None
print('------退出成功------') # 将方法名放入字典方便调用
func_dict = {
'1': register,
'2': login,
'3': add_shop_car,
'4': pay,
'5': login_out
}
while True:
print('''
1.用户注册
2.用户登录
3.添加购物车
4.结算购物车
5.退出登入
''')
# 获取用户输入的指令
chioce = input('请输入要执行的指令: ').strip()
if chioce in func_dict.keys():
func_dict[chioce]()
else:
print('------请输入正确的指令------')

hashlib加密模块和logging模块,购物车项目的更多相关文章

  1. hashib加密模块、logging模块

    hashib加密模块 # 加密模块 1.什么是加密 将明文的数据通过一些手段变成能密文数据 密文数据的表现形式一般都是一串没有规则的字符串 2.加密算法 加密算法有很多>>>(讲文明 ...

  2. hashlib加密模块、logging日志模块

    hashlib模块 加密:将明文数据通过一系列算法变成密文数据 目的: 就是为了数据的安全 基本使用 基本使用 import hashlib # 1.先确定算法类型(md5普遍使用) md5 = ha ...

  3. 2019-7-19 包、logging模块、hashlib(加密模块)、openpyxl模块、深浅拷贝

    一.包 什么是包: 它是一系列模块文件的结合体,表示形式就是一个文件夹.该文件内部通常会有一个__init__.py文件,包的本质还是一个模块,可以被调用,调包就相当于与调用__init__.py文件 ...

  4. Python基础之模块:6、hashlib模块 subprocess模块 logging模块

    目录 一.hashlib模块 1.简介 2.基本操作与用法 二.subprocess模块 1.简介 2.基本操作与用法 三.logging模块 1.简介 2.基本操作与用法 一.hashlib模块 1 ...

  5. 包、logging模块、hashlib模块、openpyxl模块、深浅拷贝

    包.logging模块.hashlib模块.openpyxl模块.深浅拷贝 一.包 1.模块与包 模块的三种来源: 1.内置的 2.第三方的 3.自定义的 模块的四种表现形式: 1.py文件 2.共享 ...

  6. Python(文件、文件夹压缩处理模块,shelve持久化模块,xml处理模块、ConfigParser文档配置模块、hashlib加密模块,subprocess系统交互模块 log模块)

    OS模块 提供对操作系统进行调用的接口 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname")  改变当前脚本工作目 ...

  7. s14 第5天 时间模块 随机模块 String模块 shutil模块(文件操作) 文件压缩(zipfile和tarfile)shelve模块 XML模块 ConfigParser配置文件操作模块 hashlib散列模块 Subprocess模块(调用shell) logging模块 正则表达式模块 r字符串和转译

    时间模块 time datatime time.clock(2.7) time.process_time(3.3) 测量处理器运算时间,不包括sleep时间 time.altzone 返回与UTC时间 ...

  8. hashlib,configparser,logging模块

    一.常用模块二 hashlib模块 hashlib提供了常见的摘要算法,如md5和sha1等等. 那么什么是摘要算法呢?摘要算法又称为哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一个长度 ...

  9. hashlib,configparser,logging,模块

    一,hashlib模块 算法介绍 Python的hashlib提供了常见的摘要算法,如MD5,SHA1等等. 什么是摘要算法呢?摘要算法又称哈希算法.散列算法.它通过一个函数,把任意长度的数据转换为一 ...

随机推荐

  1. 什么是 Spring MVC 框架的控制器?

    控制器提供一个访问应用程序的行为,此行为通常通过服务接口实现.控制器解 析用户输入并将其转换为一个由视图呈现给用户的模型.Spring 用一个非常抽象 的方式实现了一个控制层,允许用户创建多种用途的控 ...

  2. volatile 能使得一个非原子操作变成原子操作吗?

    一个典型的例子是在类中有一个 long 类型的成员变量.如果你知道该成员变量 会被多个线程访问,如计数器.价格等,你最好是将其设置为 volatile.为什么? 因为 Java 中读取 long 类型 ...

  3. 什么是编织(Weaving)?

    为了创建一个 advice 对象而链接一个 aspect 和其它应用类型或对象,称为编 织(Weaving).在 Spring AOP 中,编织在运行时执行.

  4. ACM - 最短路 - CodeForces 295B Greg and Graph

    CodeForces 295B Greg and Graph 题解 \(Floyd\) 算法是一种基于动态规划的算法,以此题为例介绍最短路算法中的 \(Floyd\) 算法. 我们考虑给定一个图,要找 ...

  5. 正则系列——JavaScript正则表达式入门心得

    我发现有个别字符被这个编辑器给刷掉了,但是灰色区域显示正常,以灰色区域代码为准 什么玩意? 在我刚开始学习编程的时候,就听过正则了,也听说正则很牛逼,懂正则的更牛逼.但是苦于没有人指点,也没有使用正则 ...

  6. 前端每日实战:134# 视频演示如何用 CSS 和 GSAP 创作一个树枝发芽的 loader

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/LJmpXZ 可交互视频 此视频是可 ...

  7. Hadoop本地编写的jar包放到集群执行时报错处理

    错误描述: 020-03-24 22:45:23,204 WARN org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor ...

  8. 使用 IDEA 创建 SpringBoot 项目(详细介绍)+ 源码案例实现

    使用 IDEA 创建 SpringBoot 项目 一.SpringBoot 案例实现源码 二.SpringBoot 相关配置 1. 快速创建 SpringBoot 项目 1.1 新建项目 1.2 填写 ...

  9. LC-54

    给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素. 示例 1: 输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2 ...

  10. JVM虚拟机类加载机制(一)

    类从被加载到虚拟机内存中开始,到卸载出内存截止,整个生命周期包括:加载.验证.准备.解析,初始化.使用.卸载七个阶段.其中验证.准备.解析三个部分统称为连接. 类初始化情况: 遇到new.getsta ...