hashlib,configparser,logging模块

今日内容

1. hashlib模块

  • 定义:内部有多种摘要算法的模块

  • 应用场景:由于数据的不安全性,为了保证用户的信息绝对的安全,所以所以用户的密码都不能使用明文的形式存储,而应该经过适当的处理以密文的形式存起来。

    • 登录验证(md5,sha-动态加盐)

      1. 对于传统摘要安全性不高,其原因在于可以进行撞库暴力破解

      2. 此时我们采取加盐的方法,方法是:

        hashlib.md5('加盐字符串'.encode('utf-8'))

        但是加盐也不是绝对安全,原因是如果有恶意用户创建多个账号,加盐后的数据库进行撞库。

      3. 在此进行动态加盐

        也就是将用户名当做本用户密码的盐,此时就相对的绝对安全了。

    • 文件的一致性校验(md5)

      • 给一个文件中的所有内容进行摘要算法得到一个md5的结果
  • 注意:hashlib模块中的所有算法都是不可逆的

  • 常用算法:

    • hashlib.md5()

      • md5算法得到的是32位16进制的数字字符组成的字符串密文,应用最广的摘要算法

      • 效率高,相对不复杂,如果只是传统摘要不安全

      • hashlib对象.update(字节格式)

        作用:生成密文

      • hashlib对象.hexdigest()

        作用:打印出密文结果

    • hashlib.sha系列

      • sha算法得到的是40位16进制的数字字符组成的字符串的密文,算法复杂度比md5更加高,以至于安全性更高。
      • 方法和hashlib.md5相同
  • 注意要点:

    • 摘要算法取摘要值支持bytes流拼接操作,也就是在文件过大时可以使用for循环对文件进行拼接校验文件是否完整。
    import hashlib
    import os
    path = 'F:\生活部分\电影\时空恋旅人\时空恋旅人_01 (1080P).bhd'
    size = os.path.getsize(path)
    obj_hash = hashlib.md5()
    with open(path,'rb') as f:
        while size:
            content = f.read(8096)          #每一次读8096个字节,直到读完为止
            size -= len(content)
            obj_hash.update(content)
        ret = obj_hash.hexdigest()
    print(ret)
    
  • 动态加盐的登录函数

import hashlib
# 注册部分
def register(usr,pwd):
    obj_hash = hashlib.md5(usr.encode('utf-8'))
    obj_hash.update(pwd.encode('utf-8'))
    hash_pwd = obj_hash.hexdigest()
    with open('user_table','a',encoding='utf-8') as f:
        f.write(usr+','+hash_pwd+'\n')
        print('注册成功。')
        return True
# 登陆部分
def login():
    usr = input('账号:').strip()
    pwd = input('密码:').strip()
    obj_hash = hashlib.md5(usr.encode('utf-8'))
    obj_hash.update(pwd.encode('utf-8'))
    hash_pwd = obj_hash.hexdigest()
    with open('user_table',encoding='utf-8') as f:
        for line in f:
            line_lst = line.strip().split(',')
            if usr == line_lst[0] and hash_pwd == line_lst[1]:
                print('登陆成功。')
                return True
        else:
            print('用户名或密码错误。')

register('Abner','123')
login()

2. configparser模块

  • 定义:

      处理配置文件信息模块
    
  • 作用:

      把文件路径记录在文件中
    
  • 配置文件格式,文件后缀名.ini

  • 模块方法:

    方法 作用
    configparser.ConfigParser() 实例化一个ConfigParser类的对象
    config['DEFAULT'] = {'a':'1','b':'2'} 在对象中创建一个组,在组中放‘a’,‘b’两个元素
    with open('my.ini','w') as configfile: config.write(configfile) 将对象config这个对象存储到’my.ini‘的文件中,这个文件这时变成了一个配置文件
    print(config['DEFAULT']['a']) 查找配置文件中['DEFAULT']组中'a'的值
    config.add_section('person') 在配置文件中增加一个组
    config.remove_section('person') 在配置文件中删除一个组
    config.set('DEFAULT','c','3') 在指定组中增加元素和对应的值
    • 注意:所有对配置文件的改动必须在最后对文件进行改动,否则改动无效

3. logging模块

  • 定义:

      处理日志文件的模块
    
  • 什么是日志?

    • 无处不在,所有程序都必须记录日志

    • 给用户看的日志

      • 购物记录
      • 视频浏览记录
      • 银行卡消费记录
    • 给内部人员看的日志

      • 技术人员日志

        • 计算的过程记录
        • 操作过程记录
      • 非技术人员日志

        • 公司管理软件

          如:谁在什么时候做了什么事,比如删除操作。

  • 方法

    import logging
    logging.debug('debug message')
    logging.info('info message')
    logging.warning('warning message')
    logging.error('error message')
    logging.critical('critical message')
    
    1. 简单配置

      import logging  
      logging.basicConfig(level=logging.DEBUG,  
                          format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  
                          datefmt='%a, %d %b %Y %H:%M:%S',  
                          filename='/tmp/test.log',  
                          filemode='w')  
        
      logging.debug('debug message')  
      logging.info('info message')  
      logging.warning('warning message')  
      logging.error('error message')  
      logging.critical('critical message')
      

      缺点:

      不能解决中文的显示问题

      不能同时向文件和屏幕输出

    2. 对象的配置

      • 解决了中文问题和同时输出问题
      • 对于文件和屏幕同时进行不同的操作
      import logging
      
      logger = logging.getLogger()
      # 创建一个handler,用于写入日志文件
      fh = logging.FileHandler('test.log',encoding='utf-8') 
      
      # 再创建一个handler,用于输出到控制台 
      ch = logging.StreamHandler() 
      formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
      
      fh.setLevel(logging.DEBUG)
      
      fh.setFormatter(formatter) 
      ch.setFormatter(formatter) 
      logger.addHandler(fh) #logger对象可以添加多个fh和ch对象 
      logger.addHandler(ch) 
      
      logger.debug('logger debug message') 
      logger.info('logger info message') 
      logger.warning('logger warning message') 
      logger.error('logger error message') 
      logger.critical('logger critical message')
      

      也可以写成函数形式:

      def log(level,msg):
          logger = logging.getLogger()
          logger.setLevel(logging.DEBUG)
          fh = logging.FileHandler('my log.log',encoding='utf-8')
          sh = logging.StreamHandler()
          fmt1 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
          fmt2 = logging.Formatter('%(asctime)s - %(name)s[line:%(lineno)d] - %(levelname)s - %(message)s')
          fh.setFormatter(fmt1)
          sh.setFormatter(fmt2)
          sh.setLevel(logging.WARNING)
          logger.addHandler(fh)
          logger.addHandler(sh)
          eval('logger.'+level.lower())(msg)
      
posted @ 2018-09-06 19:20  AbnerLing  阅读(89)  评论(0编辑  收藏  举报