hashlib加密模块、logging模块

<font size+'4px'>

今日学习内容总结

昨日作业与今日作业的整合

  import json
  import os
  import hashlib

  from random import Random

  drt_1 = os.path.dirname(__file__)

  new_drt = os.path.join(drt_1, 'db')

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

  is_log = {'username': None}

  n = 0


  def end():
      global n
      n = 3


  def log_dec(func_name):
      def inner(*args, **kwargs):
          if is_log.get('username'):
              res = func_name(*args, **kwargs)
              return res
          else:
              print('登录后方可使用')
              num_log()

      return inner


  def salt_hash(length=10):
      salt = ''
      chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
      len_chars = len(chars) - 1
      random = Random()
      for i in range(length):
          # 每次从chars中随机取一位
          salt += chars[random.randint(0, len_chars)]
      return salt


  def num_regist():
      user = input('请输入用户名:').strip()
      pasword = input('请输入密码: ').strip()
      agin_pwd = input('请确认密码:').strip()
      if not pasword == agin_pwd:
          print('两次密码不一致')
          return
      regist_path = os.path.join(new_drt, f'{user}.json')
      if os.path.isfile(regist_path):
          print('用户已存在')
          num_regist()

      salt = salt_hash()

      user_dict = {'username': user, 'password': pasword, 'balance': 10000, 'shop_car': {}, 'salt': salt}

      md5 = hashlib.md5()
      md5.update(salt.encode('utf8'))
      new_salt = md5.hexdigest()
      user_dict['salt'] = md5.hexdigest()
      md5_new = hashlib.md5()
      md5_new.update(pasword.encode('utf8'))
      user_dict['password'] = md5_new.hexdigest() + new_salt

      with open(regist_path, 'w', encoding='utf8') as f:
          json.dump(user_dict, f, ensure_ascii=False)
      print(f'{user}注册成功')


  def num_log():
      user = input('请输入用户名:').strip()
      pasword = input('请输入密码: ').strip()
      log_path = os.path.join(new_drt, f'{user}.json')

      if not os.path.isfile(log_path):
          print('该用户不存在')
          num_log()
      with open(log_path, 'r', encoding='utf8') as f:
          log_dict = json.load(f)
      salt = log_dict.get('salt')
      md5 = hashlib.md5()
      md5.update(pasword.encode('utf8'))
      m1 = md5.hexdigest() + salt
      if m1 == log_dict.get('password'):
          print('登录成功')
          is_log['username'] = user
      else:
          print('密码错误')


  @log_dec
  def shop_car_add():
      good_list = [
          ['挂壁面', 3],
          ['印度飞饼', 22],
          ['极品木瓜', 666],
          ['土耳其土豆', 999],
          ['伊拉克拌面', 1000],
          ['董卓戏张飞公仔', 2000],
          ['仿真玩偶', 10000]
      ]
      new_shop_car = {}
      while True:
          for i, j in enumerate(good_list):
              print('商品编号: %s    |    商品名称: %s    |    商品单价:%s' % (i, j[0], j[1]))

          chose = input('请输入购买商品编号或者输入y退出添加购物车:').strip()
          if chose == 'y':
              shop_path = os.path.join(new_drt, '{}.json'.format(is_log.get('username')))
              with open(shop_path, 'r', encoding='utf8') as f:
                  user_dict = json.load(f)
              shop_car_real = user_dict.get('shop_car')

              for list_name in new_shop_car:
                  if list_name in shop_car_real:
                      shop_car_real[list_name][0] += new_shop_car[list_name][0]
                  else:
                      shop_car_real[list_name] = new_shop_car[list_name]
              user_dict['shop_car'] = shop_car_real

              with open(shop_path, 'w', encoding='utf8') as f:
                  json.dump(user_dict, f, ensure_ascii=False)
              print('商品添加成功')
              break

          if not chose.isdigit():
              print('商品编号必须是数字')
              continue

          chose = int(chose)

          if not chose in range(len(good_list)):
              print('现在没有该商品')
              continue

          shop_good_list = good_list[chose]
          shop_good_name = shop_good_list[0]
          shop_good_pric = shop_good_list[1]

          shop_num = input('请输入该商品的购买数量: ').strip()
          if shop_num.isdigit():
              shop_num = int(shop_num)
              if shop_good_name not in new_shop_car:
                  new_shop_car[shop_good_name] = [shop_num, shop_good_pric]
              else:
                  new_shop_car[shop_good_name][0] += shop_num

          else:
              print('商品数量必须为数字')


  @log_dec
  def shop_car_end():
      shop_end_path = os.path.join(new_drt, '%s.json' % is_log.get('username'))

      with open(shop_end_path, 'r', encoding='utf8') as f:
          user_dict = json.load(f)

      shop_car = user_dict.get('shop_car')
      all_moeny = 0

      for good_num, good_pice in shop_car.values():
          all_moeny += good_num * good_pice

      balance = user_dict.get('balance')
      if balance >= all_moeny:
          end_money = balance - all_moeny
          user_dict['balance'] = end_money
          user_dict['shop_car'] = {}

          with open(shop_end_path, 'w', encoding='utf8') as f:
              json.dump(user_dict, f, ensure_ascii=False)

          print(f'结算成功,本次消费{all_moeny}元,还剩{end_money}元。谢谢惠顾')
      else:
          print('余额不足')


  num_dict = {'0': end, '1': num_regist, '2': num_log, '3': shop_car_add, '4': shop_car_end}

  while n < 3:
      print('''
      退出请输入  0
      注册用户请输入 1
      登录用户请输入 2
      添加购物车请输入 3
      结算购物车请输入 4
      ''')
      num = input('请输入您想执行的功能: ').strip()
      if num in num_dict:
          func_name = num_dict.get(num)
          func_name()
      else:
          print('该功能不存在')


心得体会

      这次作业主要是对我们之前的所学做一个整合使用,但是在写的过程中我会频繁的回去看自己的博客,因为很多功能有印象却忘记了。所以经常反复的写代码,是一个对方法理解的过程,也是对方法记忆的最简单粗暴的办法。在这次的作业中,因为很多知识的复合使用,导致出现了很多bug。这是对知识掌握不牢固的一种情况。比如在加入今天的加密功能中,我想加盐,结果因为重复使用md5.hexdigest()方法,导致两次输入一样的结果,密文却不一样。我的解决方法就是每次md5方法名都改一个,就不会重复了。并且在独立写代码的时候,虽然做到了分功能来写,但是做不到鸡哥代码这样的逻辑清晰。这个还需要自己下去多多努力。重复独立写代码,就是学习编程的一个重要的过程。

hashlib加密模块

      数据时代,为了防止数据安全性,防止数据泄露,会对数据进行加密,对于一些敏感数据库,更是如此。加密是最常见的保密手段,利用技术手段把重要的数据变为乱码。

      hashlib加密模块用于加密相关的操作,代替了md5模块和sha模块,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法。

      hash类型属于散列类型,把任意长度的数据通过算法函数转换成固定长度的值,它有以下特点:

      1.不可逆:无法根据散列值来还原原来的数据
      2.定长输出:无论输入的原始数据有多长,结果长度是相同的。
      3.抗修改性:输入的微小改变哪怕只有一个字符不同,会引起结果的巨大改变。
      4.强碰撞性:基本上不可能找到两个不同的数据,产生相同的hash值。

      hash算法:

      基本使用

  # md5算法
  md5 = hashlib.md5()
  
  # 将数据传递给算法对象
  md5.update(b'jason')  # 只能接收bytes类型

  # 获取加密后密文数据
  res = md5.hexdigest()
  print(res)  # 2b877b4b825b48a9a0950dd5bd1f264d
  # 在传入数据时,只要内容一致,算法结果肯定一致

      解密的了解:其实加密之后的结果是无法直接反解密的。所谓的反解密其实是暴力破解,就是反复的猜。而为了防止反解密。我们可以增加它的破解难度,也就是加盐处理。

      加盐处理就是在hashlib模块中的md5加密方法时,传入一个你自己想给的盐,或者干脆随机生成(比较安全,将盐封装在类中)。

  import hashlib


  def my_md5(s: str, salt):  # 传入密码和盐
      # 加密的函数
      # 如果传入盐的参数,则加盐
      s = str(s)  # 类型转换,转成字符串
      if salt:
          s = s + salt
      m = hashlib.md5(s.encode())  # md5加密
      return m.hexdigest()  # 返回密文


  res = my_md5('123456', 'akdjkf')
  print(res)  # 7dec48a71b71f63b07f9c24b47b11ef4

      加密的应用场景:1.密码加密如何比对。2.文件内容一致性校验。

密码加密如何比对

      用户输入的还是明文但是到了程序里面之后会采用相同的加密算法变成密文,之后拿着密文与跟数据库里面的密文比对如果一致就是密码正确不一致就是错误。

文件内容一致性校验

      作为软件的提供者,我们在提供安全软件的同时会对给该软件内容做加密处理得到一个该安全软件独有的密文。用户在下载软件之后也会对内容做相同的加密之后比对两次密文是否一致,如果是表示中途没有被修改,那就没什么问题。如果表示中途被修改过,可能存在病毒。 而针对大文件一致性校验的优化策略。可以考虑对文件内容进行切片读取并加密的操作。

logging模块

      用Python写代码的时候,在想看的地方写个print xx 就能在控制台上显示打印信息,这样子就能知道它是什么了,但是当我需要看大量的地方或者在一个文件中查看的时候,这时候print就不大方便了,所以Python引入了logging模块来记录我想要的信息。

日志等级

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

**基本使用

  import logging

  file_handler = logging.FileHandler(filename='a1.log', mode='a', encoding='utf-8', )

  logging.basicConfig(
      format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
      datefmt='%Y-%m-%d %H:%M:%S %p',
      handlers=[file_handler, ],
      level=logging.ERROR
  )

  logging.error('警告')
posted @ 2022-03-31 21:35  くうはくの白  阅读(70)  评论(0)    收藏  举报