天天看點

Python 程式設計 | 連載 21 -序列化與加密子產品

一、序列化子產品

序列化和反序列化的概念如下:

  • 序列化
    • 把不可傳輸的對象轉換成可存儲或可傳輸的過程
    • 把對象資訊轉換成字元串或者位元組串
  • 反序列化
    • 把磁盤等媒體中的資料轉換成對象
    • 把字元串或者位元組串返還為對象

Python中 number、str、list、tuple、dict 都可以進行序列化,其中字典是最常進行序列化的資料結構,注意集合 set 是不能進行序列化的。

json 和 pickle 子產品

json

子產品中的序列化和反序列化的方法

方法 參數 描述 使用 傳回值
dumps() obj 對象序列化 json.dumps([1,2]) 字元串
loads() str 反序列化 json.loads('[1,2]') 原始資料類型

pickle

子產品中的序列化和反序列化的方法

方法 參數 描述 使用 傳回值
dumps() obj 對象序列化 json.dumps([1,2]) byte
loads() byte 反序列化 json.loads('[1,2]') 原始資料類型

json 子產品和 pickle 子產品的序列化和反序列化的函數是一緻的,不同的是序列化的傳回值和反序列化的參數

import json

a = 1
b = 'stark'
c = ['stark', 'thor', 'banner']
d = (1, 3, 7, 11)
e = {'name': 'stark', 'address': 'NY'}

_a = json.dumps(a)
print(_a, type(_a))
print(json.loads(_a), type(json.loads(_a)))
_b = json.dumps(b)
print(_b, type(_b))
print(json.loads(_b), type(json.loads(_b)))
_c = json.dumps(c)
print(_c, type(_c))
print(json.loads(_c), type(json.loads(_c)))
_d = json.dumps(d)
print(_d, type(_d))
print(json.loads(_d), type(json.loads(_d)))
_e = json.dumps(e)
print(_e, type(_e))
print(json.loads(_e), type(json.loads(_e)))


# bool類型序列化和反序列化
print(json.dumps(True), type(json.dumps(True)))
print(json.loads(json.dumps(True)), type(json.loads(json.dumps(True))))

# None類型
print(json.dumps(None), type(json.dumps(None)))
print(json.loads(json.dumps(None)), type(json.loads(json.dumps(None))))
           

複制

Python 程式設計 | 連載 21 -序列化與加密子產品

需要注意的是元組反序列化之後不是元組類型而變成了清單類型。

import json

set_type = {1, 3, 5}
print(type(set_type))
print(json.dumps(set_type), type(json.dumps(set_type)))
           

複制

Python 程式設計 | 連載 21 -序列化與加密子產品

集合類型是無法進行序列化的。

使用

try-except

處理異常

import json

set_type = {1, 3, 5}
print(type(set_type))
try:
    json.dumps(set_type)
except TypeError as e:
    print(e)
finally:
    print('序列化完畢')
           

複制

Python 程式設計 | 連載 21 -序列化與加密子產品

class、function 都無法序列化

import pickle

e = {'name': 'stark', 'address': 'NY'}

_e = pickle.dumps(e)
print(_e, type(_e))
print(pickle.loads(_e), type(pickle.loads(_e)))
           

複制

Python 程式設計 | 連載 21 -序列化與加密子產品

pickle 子產品序列化傳回的是 byte 類型的資料

二、hashlib 和 base64 加密子產品

Python中常用的加密子產品主要有 hashlib 和 base64 兩個子產品

方法 參數 方法描述 使用 傳回值
md5() byte md5算法加密 hashlib.md5(b'hallo') Hash對象
sha1() byte sha1算法加密 hashlib.sha1(b'hallo') Hash對象
sha256() byte sha256算法加密 hashlib.sha256(b'hallo') Hash對象
sha512() byte sha512算法加密 hashlib.sha512(b'hallo') Hash對象

數值越高,被破解的機率越低

Hash對象中包含了兩個加密方法:

  • hash.digest() :傳回加密字元串,作為二進制資料字元串值
  • hash.hexdigest():傳回加密字元串,作為十六進制資料字元串值
import hashlib
import time

sign = 'stark'
timestamp = int(time.time())
toke = '{}{}'.format(sign, timestamp)
print(toke)

# 擷取hash對象
hash_obj_md5 = hashlib.md5(toke.encode('utf-8'))
print(hash_obj_md5)
print(type(hash_obj_md5))
hash_token = hash_obj_md5.hexdigest()
print("md5加密:{}".format(hash_token))

# 擷取hash對象
hash_obj_sh1 = hashlib.sha1(toke.encode('utf-8'))
print(hash_obj_sh1)
print(type(hash_obj_sh1))
hash_token = hash_obj_sh1.hexdigest()
print("sha1加密:{}".format(hash_token))

# 擷取hash對象
hash_obj_sh256 = hashlib.sha256(toke.encode('utf-8'))
print(hash_obj_sh256)
print(type(hash_obj_sh256))
hash_token = hash_obj_sh256.hexdigest()
print("sha256加密:{}".format(hash_token))

# 擷取hash對象
hash_obj_sh512 = hashlib.sha512(toke.encode('utf-8'))
print(hash_obj_sh512)
print(type(hash_obj_sh512))
hash_token = hash_obj_sh512.hexdigest()
print("sha512加密:{}".format(hash_token))
           

複制

Python 程式設計 | 連載 21 -序列化與加密子產品

base64 加密子產品常用的方法有:

函數 參數 描述 使用 傳回值
encodestring Byte 進行base64加密 base64.encodestring('hi') Byte
decodestring Byte 對base64解密 base64.decodestring(b'aGVsbG8=\n') Byte
encodebytes Byte 進行base64加密 base64.encodebytes(b'hi') Byte
decodebytes Byte 進行base64解密 base64.decodebytes(b'aGVsbG8=\n') Byte
import base64

encode_base64 = base64.encodestring(b'hello')
print(encode_base64)
decode_base64 = base64.decodestring(b'aGVsbG8=\n')
print(decode_base64)
           

複制

Python 程式設計 | 連載 21 -序列化與加密子產品

前兩個方法從 3.1 開始就過時類,使用後面兩個方法代替。

import base64

encode_base64 = base64.encodebytes(b'hello')
print(encode_base64)
decode_base64 = base64.decodebytes(b'aGVsbG8=\n')
print(decode_base64)
           

複制

Python 程式設計 | 連載 21 -序列化與加密子產品

base64 子產品是可以進行解密的,為了防止通過 base64 加密的字元串被解密,通常會進行加鹽或者将密碼中的某些字元使用特殊字元替換,之後再進行加密。