一、加密
在hashlib库的hash算法中,提供了很多加密算法,有 sha1()、sha224()、sha256()、sha384()、sha512()、blake2b()和 blake2s()、md5(),这些方法都通过统一接口返回一个对象,例如,使用sha256()可以创建一个SHA-256的哈希对象。
摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)。
举个例子,你写了一篇文章,内容是一个字符串 'how to use python hashlib - by Michael' ,并附上这篇文章的摘要是'2d73d4f15c0db7f5ecb321b6a65e5d6d' 。如果有人篡改了你的文章,并发表为 'how to use python hashlib - by Bob' ,你可以一下子指出Bob篡改了你的文章,因为根据 'how to use python hashlib - by Bob' 计算出的摘要不同于原始文章的摘要。
可见,摘要算法就是通过摘要函数 f() 对任意长度的数据 data 计算出固定长度的摘要 digest ,目的是为了发现原始数据是否被人篡改过。
摘要算法之所以能指出数据是否被篡改过,就是因为摘要函数是一个单向函数,计算 f(data) 很容易,但通过 digest 反推 data 却非常困难。而且,对原始数据做一个 bit 的修改,都会导致计算出的摘要完全不同。
我们以常见的摘要算法 MD5 为例,计算出一个字符串的 MD5 值:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# -- 代码1
import hashlib
md5 = hashlib.md5()
src = "have a nice day".encode('utf-8')
# md5.update(src.encode('utf-8'))
md5.update(src)
print(md5.hexdigest())
结果如下:
9daf5b463f958a9071a9efcc7fbac6d9
我们可以试着分段进行加密,代码如下:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# -- 代码2
import hashlib
md5 = hashlib.md5()
src1 = "have a".encode('utf-8')
src2 = "nice day".encode('utf-8')
# md5.update(src.encode('utf-8'))
md5.update(src1)
md5.update(src2)
print(md5.hexdigest())
得到结果为
a11b4cd51862cd42956d8271ee905ffb
这时候会发现与之前的那个结果不一样,原因是 “代码1” 和 “代码2” 之间使用 update 是计算空格的,在 src1 后面或者 src2 前面增加一个空格,就能得到和代码 “代码1” 一样的效果。
二、IO编程
很多时候,数据读写不一定是文件,也可以在内存中读写。
2.1 StringIO
StringIO顾名思义就是在内存中读写str。
要把str写入StringIO,我们需要先创建一个StringIO,然后,像文件一样写入即可:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from io import StringIO
f = StringIO()
f.write('have ')
f.write('a')
f.write(' ')
f.write('nice ')
f.write('day')
print(f.getvalue()) # getvalue()方法用于获得写入后的str
得到结果
have a nice day
要读取StringIO,可以用一个str初始化StringIO,然后,像读文件一样读取:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from io import StringIO
f = StringIO('Hello a good day!')
print(type(f)) # <class '_io.StringIO'>
while True:
s = f.readline()
if s == '':
break
print(s.strip())
# 运行结果
# <class '_io.StringIO'>
# Hello a good day!
# 运行结果
2.2 BytesIO
StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。
BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from io import BytesIO
f = BytesIO()
f.write('向往'.encode('utf-8'))
print(f.getvalue())
# 运行结果
# b'\xe5\x90\x91\xe5\xbe\x80'
# 运行结果
请注意,写入的不是str,而是经过UTF-8编码的bytes。
和StringIO类似,可以用一个bytes初始化BytesIO,然后,像读文件一样读取:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from io import BytesIO
f = BytesIO(b'\xe5\x90\x91\xe5\xbe\x80')
f.read()
# 运行结果
# b'\xe5\x90\x91\xe5\xbe\x80'
# 运行结果
三、json 模块
JSON(Javascript Object Notation),对象符号,是一种轻量级的数据交换格式
广泛应用于 AJAX 中 web 服务器和客户端的通讯的数据格式
也常用于 http 请求中
处理 json 的方法
用来处理字符串
json.loads() # 加载,把 json 转换成其他格式
json.dumps() # 颠倒,把其他格式转换成 json
用来处理文件的
json.load() # 加载,把 json 转换成文件或其他格式
json.dump() # 颠倒,把文件等其他格式转换成 json
我们可以试着把 python 的 dict 格式转换成 json 字符串格式,代码如下
import json
a = dict(name='zhouyuyao', age='21', message='you are so beautiful')
print(a)
print(type(a)) # <class 'dict'>
b = json.dumps(a) # 将字典转换成字符串
print(b)
print(type(b)) # <class 'str'>
c=json.loads(b) # 将字符串转换成字典
print(c)
print(type(c)) # <class 'dict'>
print(c['name'])
我们在处理文件的时候,通常使用 load 是从文件中拿 json 数据,把文件转换成 json 数据;
使用 dump 就是把 json 数据写入到文件中,实例如下
import json
jsondata='{"a":1,"b":2,"c":3}'
with open('a.txt','w') as f:
json.dump(jsondata,f)
with open('a.txt','r') as fr:
m=json.load(fr)
print(m)
参考资料:
1.
2. https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319556588648dd1fb0047a34d0c945ee33e8f4c90cc000
3. https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431918785710e86a1a120ce04925bae155012c7fc71e000
4. http://www.runoob.com/python/python-json.html