博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python常用模块2
阅读量:7034 次
发布时间:2019-06-28

本文共 10631 字,大约阅读时间需要 35 分钟。

hot3.png

一:hashlib模块

算法介绍:

Python摘要算法提供常见的md5和sha1算法

摘要算法又叫哈希算法和散列算法。他通过函数把任意类型数据转换成固定长度的字符串(通常是16进制表示)

摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过。

注意:****

摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算f(data)很容易,但通过digest反推data却非常困难。而且,对原始数据做一个bit的修改,都会导致计算出的摘要完全不同。

***********

我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值:

import hashlib#实例化对象名可以不是md5,可以是其他的如md5_objmd5=hashlib.md5()#对函数f()进行实例化md5.update(b'how to use md5 in python hashlib?')#导入任意长度的数据,一定是bytes类型print(md5.hexdigest())#计算MD5的hexdigest

注意两点:第一:实例化对象名可以是任意    第二:传入数据必须是bytes类型,第三:不能再元字符串加空格等,或做其他修改。

如果字符串长度过长,可以不可以分两次计算?

import hashlibmd5=hashlib.md5()md5.update(b'how to use md5')md5.update(b'in python hashlib?')print(md5.hexdigest())

两次打印结果为:

953c047ffa5aad0804aa9dd743ce76c3

953c047ffa5aad0804aa9dd743ce76c3

*********MD5优势:速度快,长度固定***********

MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。另一种常见的摘要算法是SHA1,调用SHA1和调用MD5完全类似:

import hashlibmd5=hashlib.sha1()md5.update(b'how to use md5')md5.update(b'in python hashlib?')print(md5.hexdigest())

************SHA1优势:安全,hash值长,但是费时间***************

SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示。比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法越慢,而且摘要长度更长。

 

摘要算法应用

任何允许用户登录的网站都会存储用户登录的用户名和口令。如何存储用户名和口令呢?方法是存到数据库表中:

name    | password--------+----------michael | 123456bob     | abc999alice   | alice2008

如果以明文保存用户口令,如果数据库泄露,所有用户的口令就落入黑客的手里。此外,网站运维人员是可以访问数据库的,也就是能获取到所有用户的口令。正确的保存口令的方式是不存储用户的明文口令,而是存储用户口令的摘要,比如MD5:

ername | password---------+---------------------------------michael  | e10adc3949ba59abbe56e057f20f883ebob      | 878ef96e86145580c38c87f0410ad153alice    | 99b1c2188db85afee403b1536010c2c9

考虑这么个情况,很多用户喜欢用123456,888888,password这些简单的口令,于是,黑客可以事先计算出这些常用口令的MD5值,得到一个反推表:

'e10adc3949ba59abbe56e057f20f883e': '123456''21218cca77804d2ba1922c33e0151105': '888888''5f4dcc3b5aa765d61d8327deb882cf99': 'password'

这样,无需破解,只需要对比数据库的MD5,黑客就获得了使用常用口令的用户账号。

对于用户来讲,当然不要使用过于简单的口令。但是,我们能否在程序设计上对简单口令加强保护呢?

由于常用口令的MD5值很容易被计算出来,所以,要确保存储的用户口令不是那些已经被计算出来的常用口

经过Salt处理的MD5口令,只要Salt不被黑客知道,即使用户输入简单口令,也很难通过MD5反推明文口令。

hashlib.md5("salt".encode("utf8"))

但是如果有两个用户都使用了相同的简单口令比如123456,在数据库中,将存储两条相同的MD5值,这说明这两个用户的口令是一样的。有没有办法让使用相同口令的用户存储不同的MD5呢?

如果假定用户无法修改登录名,就可以通过把登录名作为Salt的一部分来计算MD5,从而实现相同口令的用户也存储不同的MD5。

摘要算法在很多地方都有广泛的应用。要注意摘要算法不是加密算法,不能用于加密(因为无法通过摘要反推明文),只能用于防篡改,但是它的单向计算特性决定了可以在不存储明文口令的情况下验证用户口令。

 

2: configparser模块

该模块适用于配置文件的格式与windowsini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键 = 值)。创建文件来看一个好多软件的常见文档格式如下:
[DEFAULT]ServerAliveInterval = 45Compression = yesCompressionLevel = 9ForwardX11 = yes[bitbucket.org]User = hg[topsecret.server.com]Port = 50022ForwardX11 = no
如果想用python生成一个这样的文档怎么做呢?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 configfile: #打开文件 以写的方式 config.write(configfile) #写入文件句柄

如何查??

查找文件import configparserconfig = configparser.ConfigParser()# ---------------------------查找文件内容,基于字典的形式print(config.sections())  # []config.read('example.ini')print(config.sections())  # ['bitbucket.org', 'topsecret.server.com']print('bytebong.com' in config)  # Falseprint('bitbucket.org' in config)  # Trueprint(config['bitbucket.org']["user"])  # hgprint(config['DEFAULT']['Compression'])  # yesprint(config['topsecret.server.com']['ForwardX11'])  # noprint(config['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

增删改呢:

增删改操作import configparserconfig = configparser.ConfigParser()config.read('example.ini')config.add_section('yuan')   增加config.remove_section('bitbucket.org')   #删除config.remove_option('topsecret.server.com', "forwardx11")config.set('topsecret.server.com', 'k1', '11111') 修改config.set('yuan', 'k2', '22222')config.write(open('new2.ini', "w"))  写入

3 logging模块(跟日志打交道的模块)

import logginglogging.debug('debug message')logging.info('info message')logging.warning('warning message')logging.error('error message')logging.critical('critical message')

*******

注意:导入模块的时候logoing.Ddbug()  必须小写,传参数,不能大写

*******

# 默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志# 这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG)# 默认的日志格式为日志级别:Logger名称:用户输出消息。

那么如何 灵活配置日志级别,日志格式,输出位置????

mport logginglogging.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')

注意:设置等级时候:level=logging.DEBUG

logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。format:指定handler使用的日志显示格式。datefmt:指定日期时间格式。level:设置rootlogger(后边会讲解具体概念)的日志级别stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。format参数中可能用到的格式化串:%(name)s Logger的名字%(levelno)s 数字形式的日志级别%(levelname)s 文本形式的日志级别%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有%(filename)s 调用日志输出函数的模块的文件名%(module)s 调用日志输出函数的模块名%(funcName)s 调用日志输出函数的函数名%(lineno)d 调用日志输出函数的语句所在的代码行%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒%(thread)d 线程ID。可能没有%(threadName)s 线程名。可能没有%(process)d 进程ID。可能没有%(message)s用户输出的消息

logger对象配置:

import logginglogger = 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')

 

小结:

logging模块:

# logging# 操作日志的模块# 什么叫日志    # 给用户看的        # 用户的重要行为            # 登录 涉及安全            # 账单 钱    # 给开发和运维和测试人员看的        # 自测   logging.debug('一些中间结果')        # 测试   1++++++1        # 运维    # 记录        # 打印在屏幕上        # 写入文件里    # logging的优势        # 格式更加规范        # 等级更加鲜明# 简单的配置用法# import logging# logging.basicConfig(level=logging.ERROR,  ##                     format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',#                     datefmt='%a, %d %b %Y %H:%M:%S',#                     filename='test.log',#                     filemode='a')# logging.debug('debug message')  # 调试# logging.info('info message')    # 信息# logging.warning('warning message')  # 警告# logging.error('error message')      # 错误# logging.critical('critical message')  # 严重错误# 使用logger对象的用法import logging# 首先创建一个logger对象logger = logging.getLogger()#创建一个格式fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')# 创建一个 文件句柄 控制向哪个文件中输出 用什么格式fh = logging.FileHandler('test3.log',encoding='utf-8')fh.setFormatter(fmt)# 创建一个 屏幕句柄 控制向屏幕输出 用什么格式sh = logging.StreamHandler()sh.setFormatter(fmt)# 将logger对象和文件句柄,屏幕句柄绑在一起logger.addHandler(fh)logger.addHandler(sh)logger.setLevel(logging.DEBUG)     # 首先必须要整体对logger进行设置sh.setLevel(logging.INFO)fh.setLevel(logging.WARNING)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')

hashlib模块小结:

# 摘要算法# a = alex3714   ===摘要==>   174692740812ab238919# alex3714   ===摘要==> 174692740812ab238919# 登录  md5  sha    # 密码不能使用明文存储    # 密文存储 摘要算法# 校验文件一致性   md5    # 网络的上传下载    # 保证多台机器状态的一致import hashlib# md5_obj = hashlib.md5()# # md5算法的对象# md5_obj.update(b'alex3714')  # 使用md5摘要算法对'alex3714'进行摘要# res = md5_obj.hexdigest()   # 获取摘要之后的结果# print(res,type(res))  #aee949757a2e698417463d47acac93df    32位# user = input('user : ')# passwd = input('passwd : ')# md5_obj = hashlib.md5()# md5_obj.update(passwd.encode('utf-8'))# passwd = md5_obj.hexdigest()# if user == 'alex' and passwd == 'aee949757a2e698417463d47acac93df':#     print('登陆成功')# md5_obj = hashlib.sha1()# # md5算法的对象# md5_obj.update(b'alex3714')  # 使用md5摘要算法对'alex3714'进行摘要# res = md5_obj.hexdigest()   # 获取摘要之后的结果# print(res)  #8a003668a9c990f15148f9e4046e1410781533b6  40# 相同的字符串使用相同的算法 在任何时候 得到的结果都是一致的# 全世界的md5算法都是一样的# 123456  111111# md5_obj = hashlib.md5()# md5算法的对象# md5_obj.update(b'123456')  # 使用md5摘要算法对'alex3714'进行摘要# res = md5_obj.hexdigest()   # 获取摘要之后的结果# print(res,type(res))  #aee949757a2e698417463d47acac93df    32位# 123456 e10adc3949ba59abbe56e057f20f883e# 撞库# 加盐# md5_obj = hashlib.md5('盐'.encode('utf-8'))# # md5算法的对象# md5_obj.update(b'alex3714')  # 使用md5摘要算法对'alex3714'进行摘要# res = md5_obj.hexdigest()   # 获取摘要之后的结果# print(res,type(res))#aee949757a2e698417463d47acac93df    32位#0e249b9c16ea1d840ce700587cada978# 动态加盐  _ 校园管理系统# username = 'alex'   # alex alex3714#                     # egon egon5068# md5_obj = hashlib.md5(username.encode('utf-8')+'盐'.encode('utf-8'))# md5_obj.update(b'alex3714')# res = md5_obj.hexdigest()# print(res)# 校验文件一致性# with open('userinfo','rb') as f:#     md5_obj = hashlib.md5()#     md5_obj.update(f.read())#     res = md5_obj.hexdigest()#     print(res)## with open('userinfo','rb') as f:#     md5_obj = hashlib.md5()#     for line in f:#         md5_obj.update(line)   # update操作可以在hexdigest之前执行多次#                                # 分次对一个长字符串进行摘要#     res = md5_obj.hexdigest()  # 结果是对整个长字符串的摘要结果#     print(res)#56fc9aa78c2dd71d547988b24bec198a# md5_obj = hashlib.md5()# md5_obj.update(b'aaabbb')# res = md5_obj.hexdigest()# print(res)  #6547436690a26a399603a7096e876a2d## md5_obj = hashlib.md5()# md5_obj.update(b'aa')# md5_obj.update(b'abbb')# res = md5_obj.hexdigest()# print(res)  #6547436690a26a399603a7096e876a2d

 

练习:

# hashlib    # 给校园管理系统添加密文登录的功能    # 检验两个文件的一致性  md5        # func(文件a的路径,文件b的路径):            # return TRUR 或者 False# logging模块    # 给校园管理系统添加日志    # 创建 删除 关联 这种关键信息创建日志# 重写附加题    # 用堆栈思想

转载于:https://my.oschina.net/u/3657436/blog/1634673

你可能感兴趣的文章
Ubuntu时间错乱漏洞仍未修复 不知道密码可获root权限
查看>>
HyperGrid将超融合基础设施、容器带入云中
查看>>
陕西省西咸新区管委会副主任刘宇斌:打造双创示范基地
查看>>
做好觉悟了吗?弃用短信双因素身份验证!
查看>>
16WiFi退场引发迷思 公共WIFI走到尽头了吗?
查看>>
小度战胜“水哥”王昱珩,到底有没有黑幕?
查看>>
大数据预测楼市 到底有多靠谱?
查看>>
ApsaraDB for HBase - 规格的的选择
查看>>
物联网还是泄秘网?嗅探流量即可知用户动向
查看>>
数据中心网络里的链路检测技术漫谈
查看>>
信息时代大数据引爆资本市场 全产业链条遍地开花
查看>>
发挥你数据存储专家的价值
查看>>
技术 | 使用Python来学习数据科学的完整教程
查看>>
php错误提醒FastCGI Error Error Number: -2147467259 (0x80004005)错误原因及解决方法
查看>>
微软为Office和写字板软件发布零日漏洞补丁
查看>>
德驻华大使:德国正讨论立法限制中企并购德高科技企业
查看>>
ShadowBroker放大招-多种Windows零日利用工具公布
查看>>
大数据时代机器人会抢了你的饭碗吗?
查看>>
全国各地的程序员特点分析,搞笑幽默--快来对号入座
查看>>
从2G网络的没落谈物联网发展的新机遇
查看>>