首页 > 代码库 > Python函数和常用模块【day06】:json & pickle-hashlib模块

Python函数和常用模块【day06】:json & pickle-hashlib模块

本节内容

  1. json序列化
  2. pickle序列化
  3. hashlib模块

json序列化

1、dumps序列化和loads反序列化

dumps()序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
import  json   #导入json模块
 
info = {
    ‘name‘:"zhangqigao",
    "age":22
}
 
with open("test.txt","w") as f:  #以普通模式写入
    data = json.dumps(info) #把内存对象转为字符串
    f.write(data)   #写到文件中
 
#text.txt文件中的内容
{"name""zhangqigao""age"22}

loads()反序列化

1
2
3
4
5
6
7
8
9
import json
 
with open("test.txt","r") as f:  #以普通模式读
    data = json.loads(f.read())   #用loads反序列化
 
print(data.get("age"))
 
#输出
22

2、dump序列化和load反序列化

dump()序列化

1
2
3
4
5
6
7
8
9
10
11
12
import  json
 
info = {
    ‘name‘:"zhangqigao",
    "age":22
}
 
with open("test.txt","w") as f:   #文件以写的方式打开
    json.dump(info,f)    #第1个参数是内存的数据对象 ,第2个参数是文件句柄
 
#text.txt文件中的内容
{"name""zhangqigao""age"22}

 load()反序列化

1
2
3
4
5
6
7
8
9
import json
 
with open("test.txt","r") as f:   #以读的方式打开文件
    data = json.load(f)  #输入文件对象
 
print(data.get("age"))
 
#输出
22

3、序列化函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import  json
 
def sayhi(name):  #函数
    print("name:",name)
 
info = {
    ‘name‘:"zhangqigao",
    "age":22,
    "func":sayhi    #引用sayhi函数名
}
 
with open("test.txt","w") as f:
    json.dump(info,f)   #序列化info数据对象
 
#输出
 File "D:\Python\Python35\lib\json\encoder.py", line 403in _iterencode_dict
    yield from chunks
  File "D:\Python\Python35\lib\json\encoder.py", line 436in _iterencode
    = _default(o)
  File "D:\Python\Python35\lib\json\encoder.py", line 179in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <function sayhi at 0x00000000006DD510is not JSON serializable  #不支持jsom序列化

小结:

  1. dumps和loads是成对使用的,dump和load是成对使用的。
  2. dumps和loads由于序列化的是内容,所以后面要加s,但是dump和load序列化的内容是对象,所以单数。
  3. json只能处理简单的数据类型,例如:字典、列表、字符串等,不能处理函数等复杂的数据类型。
  4. json是所有语言通用的,所有语言都支持json,如果我们需要python跟其他语言进行数据交互,那么就用json格式。

pickle序列化

1、dumps序列化和loads反序列化

dumps()序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pickle
 
info = {
    ‘name‘:"zhangqigao",
    "age":22,
}
 
with open("test.txt","wb") as f:   #以二进制的形式写入
    data = pickle.dumps(info)   #序列化成字符串
    f.write(data)   #写入test.txt 文件中
 
#输出到test.txt文件中的内容
?}q (X   ageqKX   nameqX
   zhangqigaoqu.

loads()反序列化

1
2
3
4
5
6
7
8
9
import pickle
 
with open("test.txt","rb") as f: #以二进制的模式读
    data = pickle.loads(f.read())   #反序列化操作
 
print(data.get("age"))
 
#输出
22

2、dump序列化和load反序列化

dump()序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
import pickle
 
info = {
    ‘name‘:"zhangqigao",
    "age":22,
}
 
with open("test.txt","wb") as f:
    pickle.dump(info,f)  #序列化
 
#输出
?}q (X   ageqKX   nameqX
   zhangqigaoqu.

load()反序列化

1
2
3
4
5
6
7
8
9
import pickle
 
with open("test.txt","rb") as f:
    data = pickle.load(f)  #反序列化成内存对象
 
print(data.get("age"))
 
#输出
22

从上面的结果观察,json和pickle好像也没什么区别?但是别忘了,我们说,json只能序列化简单的数据类型,而pickle可以序列化python中所有的数据类型,包括函数、类等,下面我们就来看看,如何序列化函数的。还有就是,pickle序列化的是字节,而json序列化的是字符,这个要注意一下。

3、序列化函数

①序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pickle
 
def sayhi(name):   #函数
    print("hello:",name)
 
info = {
    ‘name‘:"zhangqigao",
    "age":22,
    "func":sayhi    #"func"对应的值sayhi,是函数名
}
 
with open("test.txt","wb") as f:
    data = pickle.dumps(info)
    f.write(data)
 
#输出test.txt
?}q (X   funcqc__main__
sayhi
qX   ageqKX   nameqX
   zhangqigaoqu.

②反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pickle
 
def sayhi(name):   #在反序列化中必须写上此函数,不然会报错,因为在加载的时候,函数没有加载到内存
    print("hello:",name)
 
with open("test.txt","rb") as f:
    data = pickle.loads(f.read())
 
print(data.get("age"))
 
data.get("func")("zhangqigao")  #执行函数sayhi
 
#输出
22
hello: zhangqigao   #输出的函数体中的逻辑也是可以变的,这边我就不做演示了

 小结:

  1. json值支持简单的数据类型,pickle支持所有的数据类型。
  2. pickle只能支持python本身的序列化和反序列化,不能用作和其他语言做数据交互,而json可以。
  3. pickle序列化的是整个的数据对象,所以反序列化函数时,函数体中的逻辑变了,是跟着心的函数体走的。
  4. pickle和json在3.0中只能dump一次和load一次,在2.7里面可以dump多次,load多次,anyway,以后只记住,只需要dump一次,load一次就可以了。

hashlib模块

一、简述

  我们写程序中,经常需要对字符串进行MD5加密,python中也支持这种加密,下面说说,这个加密模块:hashlib。

二、MD5加密

  原则:只要你的输入是固定的,你的输出也一定是固定的。MD5是在hash上更改的,主要做文件的一致性

1、md5加密

1
2
3
4
5
6
7
8
9
10
11
12
import hashlib
 
= hashlib.md5()  #创建一个MD5对象
m.update(b"zhang")   #在python3中需要是2进制的值,所以字符串前加b
print(m.hexdigest())  #以16进制打印MD5值
#输出
d0cd2693b3506677e4c55e91d6365bff
 
m.update(b"qigao")
print(m.hexdigest())
#输出
0bfca190ecc60e44cbc739ca9c252133

2、文件内容MD5值

说明:如果我们想得到一个文件所有内容的MD5值,我们所做的方法是循环这个文件,获取每行的MD5值,但是这样生成的MD5值的效率会变慢,因为每一行都需要计算。这样我们还不如直接把文件的所有内容加载出来,直接计算它的MD5值,这样反而快些。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import hashlib
 
= hashlib.md5()  #创建MD5对象m
m.update(b"zhang")
print(m.hexdigest())
#输出
d0cd2693b3506677e4c55e91d6365bff
 
m.update(b"qigao")
print(m.hexdigest())
#输出
0bfca190ecc60e44cbc739ca9c252133
 
m2 = hashlib.md5()    #创建MD5对象m2
m2.update(b"zhangqigao")
print(m2.hexdigest())
#输出
0bfca190ecc60e44cbc739ca9c252133

 注:由上面的代码可以看出,你读到最后一行的字符串的MD5值跟一下子读取所有内容的MD5值是一样的,这是为什么呢?其实这边update做了一个拼接功能,m.update(b"zhang")是返回的字符串"zhang"的MD5值,但是到了第二个m.update("qigao")的值并不是"qigao"的字符串的MD5值,它需要拼接前面的字符串,应该是m.update(b"zhangqigao")的MD5值,所以相当于m.update(b"zhang"),m.update(b"qigao") = m.update(b"zhang"+b"qigao")。

三、sha1加密

1
2
3
4
5
6
7
8
import hashlib
 
hash = hashlib.sha1()
hash.update(b"zhangqigao")
print(hash.hexdigest())
 
#输出
c8b2a6571067f92133b5b43a085f1ddd36e8c3fb

四、sha256加密

说明:sha256用的比较多,相比MD5要更加的安全

1
2
3
4
5
6
7
8
import hashlib
 
hash = hashlib.sha256()
hash.update(b"zhangqigao")
print(hash.hexdigest())
 
#输出
0634de5fe3d009fd0ec76ab3d97ab0fe37969b696e8d6550797cf3b446dd78ba

五、sha384加密

1
2
3
4
5
6
7
8
import hashlib
 
hash = hashlib.sha384()
hash.update(b"zhangqigao")
print(hash.hexdigest())
 
#输出
3489c64e31671094ca1afde35fd31ee9b09cdb90c3728f31696829e8a56be311e1405d537179e62d236e6d70a4f13ff4

六、sha512加密

1
2
3
4
5
6
7
8
import hashlib
 
hash = hashlib.sha512()
hash.update(b"zhangqigao")
print(hash.hexdigest())
 
#输出
cb09fd5a519b2b075f4aa5965a39657df900fff832b73d161a426512b6023ab8c1c0872a7b2d50055cbd75c4b6f374cda0615be9530f7f4b7dc08ab3f266325d

注意:

  1. 以上这几种,其实都是对MD5加密的不同算法
  2. 其中sha256用的最多,比MD5要安全的多
  3. 有些公司会用加盐方式加密,比如:把字符串"zhangqigao",通过一定的算法变成"zhang.qi.gao",当然这种算法自己肯定要知道,然后MD5加密,当然每个公司的加盐方式是不一样的。

七、hmac加密

其实以上还不是最牛的,最牛的是下面这种,叫hmac加密,它内部是对我们创建key和内容进行处理再进行加密。

散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;

一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,这样就能验证消息的真实性,及发送者的合法性了。

代码如下:

1
2
3
4
5
6
7
import hmac #导入hmac模块
 
hash = hmac.new(b"zhang",b"qigao"#zhang是key,qigao是内容
print(hash.hexdigest())
 
#输出
2f124c86aeb5142246198f77a142e855

Python函数和常用模块【day06】:json & pickle-hashlib模块