模块补充,hashlib,logging,configparser模块

复习
多态:python 自带多态
    java的多态是通过继承来实现的
钻石继承
    新式类,继承object类
        找名字的时候,广度优先
        python3中全是新式类,默认继承object
        mro方法,super方法
    经典类
        只会出现在python2中,不主动继承object
        找名字的时候,深度优先
封装
    私有的 __名字
        私有的对象属性
        私有的静态属性
        私有方法
    不能从外部调用,不能被子类继承
    在类的内部使用时,自动变形为:_类__名字
@property           把一个方法伪装成一个属性
    @名字.setter 在修改一个属性的时候调用这个方法
    @名字.deleter 在 del.属性名 的时候调用这个方法
@classmothod
    类方法
    调用者是一个类
    有默认参数cls,cls表示当前类
    在什么时候使用类方法?
        只是用类中的静态变量
        或者类方法或者静态方法的时候
@staticmethod   静态方法
    调用者也是一个类
    没有默认必须传的参数
    什么时候用静态方法?
        既不会用到对象的资源也不会用到类的资源的时候

hash()
把一个数据转换成一个数字的算法
在同一次执行的过程中,对同一个可哈希的值进行计算,得出的结果总是相同的
做什么用的
有什么特点
基础数据类型的时候
不可变数据类型可哈西
可变数据类型不可哈希

print(hash('abc'))#8863356200575210437
print(hash('abc'))#8863356200575210437
print(hash('abc'))#8863356200575210437

字典
集合
在数据的储存方面提供优化的
为什么同一个值计算hash值每次运行结果不同?
每次执行所获得的的内存空间都不一定相同,所以多次执行统一代码得到的hash值可能不同
hashlib模块
hashlib的特点
是一个模块,提供多种算法
同一字符串用同一算法进行加密,结果总是相同的
同一字符串用不同的算法进行加密,结果总是不同的

为什么使用hashlib进行加密呢?
1.登录
123-->转换-->转换之后的结果储存在文件里
用户登录的时候
输入密码-->用同样的方法转换-->结果于文件中匹配
import hashlib
hashlib.sha1()
md5算法,sha 算法
字符串-->加密的结果
md5算法--暴力破解,撞库
sha算法--是一个算法集
随着后面的数字越大,计算的时间越长,结果越长,越安全

md5_obj=hashlib.md5()#hashlib实例化
md5_obj.update('123'.encode('utf-8'))#将密码进行变形
print(md5_obj.hexdigest())#202cb962ac59075b964b07152d234b70

md5_obj=hashlib.md5()#hashlib实例化
md5_obj.update(''.encode('utf-8'))#将密码进行变形
print(md5_obj.hexdigest())#d41d8cd98f00b204e9800998ecf8427e 空内容也可以哈希

简单的登录练习
def login():
    username=input('请输入你的账号:').strip()#xiaozhi
    password=input('请输入你的密码:').strip()#123
    md5_obj=hashlib.md5()#hashlib实例化
    md5_obj.update(password.encode('utf_8')))#将密码进行变形
    str_md5=md5_obj.hexdigest())#将密码进行加密
    # print(str_md5)
    with open('userinfo',encoding='utf-8')as f:
        for line in f:
            name,pwd=line.strip().split(',')#必须去空格
            if name==username and pwd==str_md5:
                print('恭喜你登录成功')
                break
login()

sha算法
sha_obj=hashlib.sha1()
sha_obj.update('123'.encode('utf-8'))
str_sha=sha_obj.hexdigest()
print(str_sha,len(str_sha))#40位数的密码 40bd001563085fc35165329ea1ff5c5ecbdbbeef

# 密码加盐
md5_obj=hashlib.md5(''.encode('utf-8'))
md5_obj.update(b'123')
str_md5=md5_obj.hexdigest()
print(str_md5,len(str_md5))#  32位的密码 79c9808728cbae3d9c91984fdfc5a93d

def login():
    username=input('请输入你的账号:').strip()#xiaoyang
    password=input('请输入你的密码:').strip()#123
    md5_obj=hashlib.md5(''.encode('utf-8'))#往密码里加了一个糖
    md5_obj.update(password.encode('utf-8'))#将密码摘要
    str_md5=md5_obj.hexdigest()#将密码加密
    # print(str_md5)
    with open('userinfo')as f:
        for line in f:
            name,pwd=line.strip().split(',')
            if name==username and pwd==str_md5:
                print('恭喜你登录成功')
                break
login()

恶意注册 500个 可以试出简单的密码

动态加盐
每个用户的密码的密文的盐都不一样,例如,用name做盐

import hashlib
def login():
    username=input('请输入你的账号:').strip()#xiaoli
    password=input('请输入你的密码:').strip()#123
    md5_obj=hashlib.md5(username.encode('utf-8'))#往密码里加了一个username的盐,变成动态加密
    md5_obj.update(password.encode('utf-8'))#将密码摘要
    str_md5=md5_obj.hexdigest()#将密码加密
    # print(str_md5)
    with open('userinfo')as f:#要注意把加密后的密码放到文件中
        for line in f:
            name,pwd=line.strip().split(',')
            if name==username and pwd==str_md5:
                print('恭喜你登录成功')
                break
login()

md5的第一个功能--登录验证
sha系列和md5的用法相同
摘要算法的漏洞--撞库
加盐的摘要算法--恶意注册
动态加盐的摘要算法--完美

md5的第二个功能--校验文件的一致性
import os#和路径相关的问题,用os模块
with open(r'D:\untitled3\day22\userinfo',encoding='utf-8')as f:#不要引用当前文件的内容,下面执行相同代码时算出的值会不样。
    file_size=os.path.getsize(r'D:\untitled3\day22\userinfo')#返回文件的大小
    md5_obj=hashlib.md5()
    while file_size>0:
        str_content=f.read(1024)
        md5_obj.update(str_content.encode('utf-8'))
        file_size-=1024
    str_md5=md5_obj.hexdigest()
    print(str_md5)#

def size(a):#
    with open(a, encoding='utf-8')as f:
        file_size = os.path.getsize(a)
        md5_obj1 = hashlib.md5()
        for line in f:
            md5_obj1.update(line.encode('utf-8'))
        str_md5 = md5_obj1.hexdigest()
        return str_md5  #
print(size(r'D:\untitled3\day22\userinfo'))

校验文件的一致性:md5速度快

logging模块
****会调用就行,不要求背
写日志的模块
在代码遇到问题的时候 —— 写给程序员看的
    一些中间结果起到的排错作用
    需要打印出来 —— 在排错的过程中
    在真正提供服务的时候 —— 不需要
记录一些用户的行为 —— 写给用户看的
                 —— 写给公司看的

记录一个字符串
写文件 print
logging模块???
格式规范
帮你把日志的紧急情况进行分类

import logging
logging.debug('debug message')  # 调试的时候
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')  # 批判的,比报错更严重
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
filename = 'test.log'        )
logging.debug('debug message')  # 调试的时候
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')  # 批判的

使用logger对象的形式进行配置
import logging
logger = logging.getLogger()
#
fmt = logging.Formatter('%(asctime)s -%(filename)s- %(name)s - %(levelname)s - %(message)s') # 格式
# 人 —— 练会了吸星大法
fh = logging.FileHandler('log',encoding='utf-8')  # 创建了一个文件操作符
fh.setFormatter(fmt)         #给文件操作符设置一个格式
logger.addHandler(fh)  # 给logger对象添加fh武功

在屏幕上输入
sh = logging.StreamHandler()
sh.setFormatter(fmt)
sh.setLevel(logging.WARNING)
logger.addHandler(sh)

# logging.StreamHandler()  # 创建了一个屏幕操作符
logger.setLevel(logging.DEBUG)

logger.debug('debug message')  # 调试的时候
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')  # 批判的

注意事项
在哪一行 写了 logger.debug('>>>>>')

configparser模块

import configparser#*了解
config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
                      'Compression': 'yes',
                     'CompressionLevel': '9',
                     'ForwardX11':'yes'
                     }
config['bitbucket.org'] = {'User':'hg'}
config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'}
with open('example.ini', 'w') as f:
   config.write(f)
import configparser

config = configparser.ConfigParser()
print(config.sections())        #  []
config.read('example.ini')
print(config.sections())        #   ['bitbucket.org', 'topsecret.server.com']
print('bytebong.com' in config) # False
print('bitbucket.org' in config) # True
print(config['bitbucket.org']["user"])  # hg
print(config['DEFAULT']['Compression']) #yes
print(config['topsecret.server.com']['ForwardX11'])  #no
print(config['bitbucket.org'])          #<Section: bitbucket.org>
for key in config['bitbucket.org']:     # 注意,有default会默认default的键
    print(key)
print(config.options('bitbucket.org'))  # 同for循环,找到'bitbucket.org'下所有键
print(config.items('bitbucket.org'))    #找到'bitbucket.org'下所有键值对
print(config.get('bitbucket.org','compression')) # yes       get方法Section下的key对应的value

tast

有两个文件作为参数
判断这两个文件是否相同,如果相同,返回True,否则返回False
import os
import hashlib
def consistency(a,b):
    with open(a, encoding='utf-8')as f1:
        md5_obj = hashlib.md5()
        for line in f1:
            md5_obj.update(line.encode('utf-8'))
        str_md5 = md5_obj.hexdigest()
        # return str_md5  #函数中间不能用return,否则就打断循环了

    with open(b, encoding='utf-8')as f2:
        md5_obj1 = hashlib.md5()
        for line in f2:
            md5_obj1.update(line.encode('utf-8'))
        str_md51 = md5_obj1.hexdigest()

    if str_md51==str_md5:
        return True
    else:
        return False

print(consistency('userinfo','复习'))#'userinfo','复习'

 










 

posted @ 2018-05-30 21:30  老虎死了还有狼  阅读(60)  评论(0)    收藏  举报