代码改变世界

configparser模块和hashlib模块

2019-08-19 23:44  小罗世界  阅读(119)  评论(0)    收藏  举报

configparser模块中ConfigParser是配置文件,

ConfigParser模块在Python3修改为configparser,这个模块定义了一个ConfigeParser类,该类的作用是让配置文件生效。配置文件的格式和window的ini文件相同,大致如下:
【section】
name = value
name:value
用 = 或 : 来赋值
section可以理解为一个模块,比如登录的时候,这个section可以叫login,下面放着username和password
该模块主要使用模块中RawConfigParser(),ConfigParser()、SafeConfigParse()这三个方法(三选一),创建一个对象使用对象的方法对配置文件进行增删改查操作
主要介绍ConfigParser()下的方法
涉及增删改的操作 都需要使用write()方法之后才会生效
add_section():用来新增section
set():用来新增对应section下的某个键值对
import  configparser 
config = configparser.ConfigParser()
file = 'D:/PycharmProjects/Vuiki/Config/config.ini'
config.read(file)
config.add_section('login')
config.set('login','username','1111')
config.set('login','password','2222')
with open(file,'w') as configfile:    
  config.write(configfile)

配置文件为:

[login]

username:1111

password:2222

read()方法是用来读取配置文件的,如果不加上read()方法,写入是直接从头开始写的,使用了read()之后,是从读取完后的光标开始写入,类似追加模式'a'一样。可能有疑惑,既然有追加模式,直接把with里面的'w'换成'a'就可以,干嘛还要读一次
将上面的代码修改一下,将username和password的值修改一下
import  configparser 
config = configparser.ConfigParser()
file='D:/PycharmProjects/Vuiki/Config/config.ini'
config.read(file)
config.set('login','username','2222')
config.set('login','password','3333')
with open(file,'w') as configfile:    
    config.write(configfile)

 

 配置文件为:

[login]

username:2222

password:3333

 
会发现username和password的值被修改了,如果使用'a'模式,会发现报错,没有找到login这个section。
就算把上面代码中加上config.add_section('login')也只会在后面进行追加新增,而不会做修改操作
所以考虑到把方法封装的缘故,使用read()和'w'写入模式,来实现追加新增,修改配置文件
 

读取

使用get()方法可以获得指定section下某个键的值

import  configparser 
 config = configparser.ConfigParser()
file = 'D:/PycharmProjects/Vuiki/Config/config.ini'
config.read(file)
username = config.get('login','username')
password = config.get('login','password')
print(username,password)
 

结果:

2222 3333

sections()方法返回可用的section,默认DEFAULT是不会返回的

import  configparser 
config = configparser.ConfigParser()
file = 'D:/PycharmProjects/Vuiki/Config/config.ini'
config.read(file)
username = config.sections()
print(username)
 

 

options()返回对应section下可用的键

import  configparser 
config = configparser.ConfigParser()
file = 'D:/PycharmProjects/Vuiki/Config/config.ini'
config.read(file)
username = config.options('login')
print(username)
 

输出为:

['username','password']

 

has_section()方法判断section是否存在,存在返回True,不存在返回False

import  configparser
 config = configparser.ConfigParser()
file = 'D:/PycharmProjects/Vuiki/Config/config.ini'
config.read(file)
test1 = config.has_section('login')
test2 = config.has_section('test')
print(test1)
print(test2)

 

输出结果为:

True

Flase

 

has_option()方法判断section下,某个键是否存在,存在返回True,不存在返回False

import  configparser 
config = configparser.ConfigParser()
file = 'D:/PycharmProjects/Vuiki/Config/config.ini'
config.read(file)
test1 = config.has_option('login','username')
test2 = config.has_option('login','pass')
print(test1)
print(test2)
 

输出结果为:

True

Flase

 

删除

remove_section()方法删除某个section

remove_option()方法删除某个section下的键

import  configparser
 config = configparser.ConfigParser()
file='D:/PycharmProjects/Vuiki/Config/config.ini'
config.read(file)
config.remove_option('login','username')
config.remove_option('login','password')
config.remove_section('login')
with open(file,'w') as configfile:   
     config.write(configfile)
 

一定要先read()到内存,不然删除报错

一. hasllib的基本概念        

1、什么叫hash:hash是一种算法(不同的hash算法只是复杂度不一样)(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法),该算法接受传入的内容,经过运算得到一串hash值
2、hash值的特点是(hash值/产品有三大特性:):
2.1 只要传入的内容一样,得到的hash值必然一样=====>要用明文传输密码文件完整性校验
2.2 不能由hash值返解成内容=======》把密码做成hash值,不应该在网络传输明文密码(只能有内容返回hash值)
2.3 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的(如从网上下载文件要进行hash校验,保证网络传输没有丢包)
基于2.1和2.3可以做文件下载一致性的校验
基于2.1和2.2可以对用户密码进行加密
hash算法就像一座工厂,工厂接收你送来的原材料(可以用m.update()
为工厂运送原材料),经过加工返回的产品就是hash值

二.如何产生hash值之三个阶段

import hashlib         #(hash库)
import hashlib
# # ######## 256 ########
# # 1、造出hash工厂
hash = hashlib.sha256('898oaFs09f'.encode('utf8'))     #同一种hash算法得到的长度是固定的
# # 2、运送原材料
hash.update('alvin'.encode('utf8'))                     #工厂传入的原材料都是bytes类型
# # 3、产出hash值
print(hash.hexdigest())  # e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7



import hashlib
m=hashlib.md5()                               #括号内也可以传值,类型也要求是bytes类型
m.update('你好呀!'.encode('utf-8'))
print(m.hexdigest())                          #9e49eb8e75b9a87424e388b862ea5f83

# 与上述hash的结果一样
import hashlib
m=hashlib.md5(''.encode('utf-8'))          #括号内也可以传值,类型也要求是bytes类型
m.update('好呀!'.encode('utf-8'))
print(m.hexdigest())

三、校验文件的一致性(如何保证下载的文件过程中不丢包,保证下载数据的完整性)

# -----------文件一致校验----------------
'''可以拷贝一个文件放在两个不同的盘中,然后通过判断两个文件的hash值是否相等,判断两个文件是否是同一个文件'''
import hashlib
m = hashlib.md5()
with open(r'G:/logging模块配图.png','rb') as f:
    for line in f:
        m.update(line)
print(m.hexdigest())          #47a6b079cc33a4f312786b46e61e0305

import hashlib
m = hashlib.md5()
with open(r'H:/logging模块配图.png','rb') as f:
    for line in f:
        m.update(line)
print(m.hexdigest())

四、对明文密码进行加密

# 应用:对明文密码进行加密(暴力破解-------用明文密码用一种算法算出一个hash值,与截取的hash值进行比对,比对成功说明明文密码一致,就可以破解用户的密码)
'''如用户在某网站进行注册信息,这个时候防止信息被恶意拦截获取,可以对用户明文密码进行加密,存成hash值得形式,这样用户每次登陆虽然输的是明文密码,校验hash值即可'''
password=input('>>>>>:').strip()
import hashlib
m=hashlib.md5()
m.update(password.encode('utf-8'))
print(m.hexdigest())             #00dcbdaede875d5e23f1f9f64c7849ef


# 对密码进行加盐(暗号)----------进一步加强密码的安全性
password=input('>>>>>:').strip()
import hashlib
m=hashlib.md5()
m.update('一行白鹭上青天'.encode('utf-8'))         #对密码加盐
m.update(password.encode('utf-8'))
print(m.hexdigest())

五、破解用户注册的密码

# 重点
'''模拟撞库破解密码'''
import hashlib
passwds=[                      #可以通过random实现对passwds中的内容
    'alex3714',
    'alex1313',
    'alex94139413',
    'alex123456',
    '123456alex',
    'a123lex',
    ]

def make_passwd_dic(passwds):                #通过明文密码列表,造出与之对应的hash值得字典
    dic={}
    for passwd in passwds:
        m=hashlib.md5()                      #使用md5算法,造了一个工厂
        m.update(passwd.encode('utf-8'))     #给工厂运送原材料(即我们要加密的内容)
        dic[passwd]=m.hexdigest()            #产出hash值(即最终的产品),将其加入到我们事先造好的空字典中,字典形式:{密码:hash值}
    return dic

def break_code(cryptograph,passwd_dic):      #判断拦截的hash值是否与字典中事先造好的hash值相等,相等则说明成功进行破解
    for k,v in passwd_dic.items():
        if v == cryptograph:
            print('密码是===>\033[46m%s\033[0m' %k)

cryptograph='aee949757a2e698417463d47acac93df'     #我们拦截拿到的密码,经过加密的hash值
break_code(cryptograph,make_passwd_dic(passwds))   #将要破解的密码hash值,和事先造好的hash的字典当做函数的实参传给对应的形参

六、hmac模块的加密方式,与hashlib类似

'''python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密:'''
import hmac
h = hmac.new('天王盖地虎'.encode('utf8'))          #hmac必须要加盐
h.update('hello'.encode('utf8'))
print(h.hexdigest())                 #1abaae8f65f68f2695a8545c5bc8e738

#要想保证hmac最终结果一致,必须保证:
#1:hmac.new括号内指定的初始key一样
#2:无论update多少次,校验的内容累加到一起是一样的内容

# 下面单重方式得到的结果是一样的
import hmac
h1=hmac.new(b'tom')          #初始值必须保证一致,最终得到的结果就会不一样
h1.update(b'hello')
h1.update(b'world')
print(h1.hexdigest())

h2=hmac.new(b'tom')         #初始值必须保证一致,最终得到的结果就会不一样
h2.update(b'helloworld')
print(h2.hexdigest())

h3=hmac.new(b'tomhelloworld')   #初始值不一样,所以与上面两种的结果不一样
print(h3.hexdigest())

'''
0426ccec3b134e8c18fdcefee841ef25
0426ccec3b134e8c18fdcefee841ef25
ff1214d895bbaf5f1847db4ebae8212e
'''

 

configparser和hashlib应用

实现简单的用户注册和登录

import configparser
import hashlib
from homework.conf import infopath
config = configparser.ConfigParser()
# logpath = r'E:\pycharm\homework\data\log.ini'
logpath = config.read(infopath.logpath)[0]
# print(logpath)
class Log:
    @staticmethod
    # 注册功能
    def log():
        config.read(logpath)
        section = input('sections实名:')
        username = input('username:').encode('gbk')
        password = input('password:')
        y_password = input('y_password:')
        md5 = hashlib.md5()
        md5.update(password.encode('gbk'))
        pwd = md5.hexdigest()
        md = hashlib.md5()
        md.update(y_password.encode('gbk'))
        y_pwd = md.hexdigest()
        if pwd==y_pwd:
            config.add_section(section)
            config.set(section,'username',username.decode('gbk'))
            config.set(section,'password',pwd)
            with open(logpath,'w',encoding='gbk')as f:
                config.write(f)
                print('注册成功')
        else:
            print('注册失败')
    @staticmethod
    #登录功能
    def getinfo():
        section = input('section实名:')
        username = input('username:').encode('gbk')
        password = input('password:')
        md5 = hashlib.md5()
        md5.update(password.encode('gbk'))
        pwd = md5.hexdigest()
        config.read(logpath)
        if section in config.sections():
            if config.get(section,'username')==username.decode('gbk') and config.get(section,'password')==pwd:
                print('登录成功')
            else:
                print('登录失败')
        else:
            print('实名错误')


l = Log()
l.log()
l.getinfo()