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. 包、logging模块、hashlib模块、openpyxl模块、深浅拷贝

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

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

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

  6. 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时间 ...

  7. hashlib,configparser,logging模块

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

  8. hashlib,configparser,logging,模块

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

  9. python3之xml&ConfigParser&hashlib&Subprocess&logging模块

    1.xml模块 XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言. XML 被设计用来传输和存储 ...

随机推荐

  1. OOD沉思录 --- 类和对象的关系 --- 包含关系3

    4.7 类包含的对象数目不应当超过开发者短期记忆数量,这个数目通常应该是6左右 4.8 让系统在窄而深的包含体系中垂直分布 假设有如下两份菜单: 正餐 --->甜瓜 --->牛排 ---& ...

  2. 配置hibernate出现的错误一

    问题:2011-04-18 11:35:46,734 ERROR [org.hibernate.tool.hbm2ddl.SchemaUpdate] - could not complete sche ...

  3. double的值太大,以及补0

    当double的值太大的时候,比如1000000000 用DecimalFormat: double d = 1.0E7; System.out.println(new DecimalFormat(& ...

  4. 简单的谈一下.NET下的AOP

    AOP有着它优良的好处, 从一个层面上去关心一个问题, .NET对此有良好的支持.如果硬生生的看MSDN不理解里面的思想是有掉入深渊的感觉的. 为了理解AOP的机制, 我们从需求开始说起,实现AOP就 ...

  5. hdu 5424 Rikka with Graph II(dfs+哈密顿路径)

    Problem Description   As we know, Rikka is poor at math. Yuta is worrying about this situation, so h ...

  6. php中get_headers函数的作用及用法的详细介绍

    get_headers() 是PHP系统级函数,他返回一个包含有服务器响应一个 HTTP 请求所发送的标头的数组.如果失败则返回 FALSE 并发出一条 E_WARNING 级别的错误信息(可用来判断 ...

  7. python大法好——飞机大战

    import pygame from pygame.locals import * import time def key_control(hero_temp): # 获取事件,比如按键等 for e ...

  8. Crane (POJ 2991)

    //线段树 延迟标签 // #include <bits/stdc++.h> using namespace std; const int maxn=1e4+5; double x[max ...

  9. Step4:SQL Server 跨网段(跨机房)复制

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 解决方案(Solution) 搭建过程(Process) 注意事项(Attention) 参考 ...

  10. PCL点云特征描述与提取(2)

    点特征直方图(PFH)描述子 正如点特征表示法所示,表面法线和曲率估计是某个点周围的几何特征基本表示法.虽然计算非常快速容易,但是无法获得太多信息,因为它们只使用很少的几个参数值来近似表示一个点的k邻 ...