第12次課

hashlib

haslib模塊爲不一樣的安全哈希/安全散列(Secure Hash Algorithm)和信息摘要算法(Message Digest Algorithm)實現了一個公共的、通用的接口。haslib模塊提供了不少算法的函數實現,例如:md五、sha一、sha22四、sha25六、sha38四、sha512等。

此處簡單介紹下集中數據加密方式html

數據加密方式 描述 主要解決問題 經常使用算法
對稱加密 數據加密和解密使用相同的密鑰 數據的機密性 DES,AES
非對稱加密 也叫公鑰加密,指數據加密和解密使用不一樣的密鑰(密鑰對) 身份驗證 DSA,RSA
單向加密 只能加密數據,不能解密數據 數據的完整性驗證 MD5,SHA系統算法

摘要算法又稱哈希算法、散列算法。它經過一個函數,把任意長度的數據轉換爲一個長度固定的字符串(一般用16進制字符串表示)。經常使用的是md5算法。
hashlib模塊對應的屬性和函數python

  • hselib.new(name[, date])
    通用的哈希對象構造函數,用於構造指定的哈希算法對應的哈希對象。其中name用於指定哈希算法名稱,如md5sha1,不區分大小寫;data可選,表示初始數據。web

    1
    2
    3
    >>> import hashlib
    >>> hashlib.new('md5')    #構建hash對象
    <md5 HASH object @ 0x00000131AE948AD0>
  • hashlib.算法名稱()
    能夠直接經過具體的哈希算法名稱對應的函數獲取哈希對象,如hashlib.md5()等。
    hashlib.md5()和hashlib.new(‘md5’)是等價的。算法

    1
    2
    3
    >>> import hashlib
    >>> hashlib.md5()
    <md5 HASH object @ 0x00000131AE9489E0>
  • hashlib.algorithms_guaranteed
    它的值是該模塊在全部平臺都支持的哈希算法的名稱集合。json

    1
    2
    3
    >>> import hashlib
    >>> hashlib.algorithms_guaranteed
    {'sha384', 'blake2b', 'sha3_384', 'shake_128', 'sha3_256', 'sha3_224', 'md5', 'sha3_512', 'blake2s', 'sha224', 'shake_256', 'sha256', 'sha512', 'sha1'}
  • hashlib.algorithms_available
    當前運行python解釋器中可用的哈希算法的集合。algorithms_guaranteed是它的子集。緩存

    1
    2
    3
    >>> import hashlib
    >>> hashlib.algorithms_available
    {'md4', 'sha3_384', 'shake_128', 'whirlpool', 'SHA224', 'blake2s', 'ripemd160', 'MD4', 'sha1', 'sha384', 'SHA384', 'ecdsa-with-SHA1', 'md5', 'SHA256', 'DSA-SHA', 'SHA1', 'sha3_512', 'shake_256', 'sha', 'sha256', 'sha512', 'DSA', 'RIPEMD160', 'blake2b', 'dsaEncryption', 'SHA512', 'sha3_224', 'sha224', 'SHA', 'sha3_256', 'MD5', 'dsaWithSHA'}

hash對象對應的屬性和方法安全

  • hash.update()
    更新哈希對象所要計算的數據,屢次調用爲累加效果。
    m.update(a);m.update(b)等價於m.update(a+b)
  • hash.digest()
    返回傳遞給update()函數的全部數據的摘要信息(二進制格式的字符串)
  • hash.hexdigest()
    返回傳遞給update()函數的全部數據的摘要信息(十六進制格式的字符串)
  • hash.copy()
    返回該哈希對象的一個copy(「clone」),這個函數能夠用來有效的計算共享一個公共初始化子串的數據的摘要信息。
  • hash.digest_size
    hash結果的字節大小,即hash.digest()方法返回結果的字符串長度。該值對於哈希對象是固定的。md5:16,sha1:20, sha224:28。
  • hash.name
    當前哈希對象對應的哈希算法的標準名稱(小寫),能夠直接傳遞給hashlib.new()函數來建立另一個同類型的哈希對象。
    使用示例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    >>> import hashlib
    >>> m = hashlib.md5()    #建立hash對象
    >>> m.update('hello world'.encode('utf-8'))    #更新hash對象的計算數據
    >>> print(m)
    <md5 HASH object @ 0x00000131AE9489E0>
    >>> print(m.hexdigest())    #返回對應數據摘要信息(十六進制)
    5eb63bbbe01eeed093cb22bb8f5acdc3
    >>> print(m.digest())    #返回對應數據摘要信息(二進制)
    b'^\xb6;\xbb\xe0\x1e\xee\xd0\x93\xcb"\xbb\x8fZ\xcd\xc3'
    >>> print(m.name)    #返回使用的哈希算法
    md5
    >>> print(m.digest_size)    #返回字符串長度
    16

注意點:服務器

  1. 實際使用中都是獲取十六進制的字符串,也就是使用hash.hexdigest()
  2. 使用hashlib模塊通常是3步,經過hashlib.md5()建立哈希對象;經過update()追加須要計算的數據;經過hexdigest()獲得數據對應的十六進制字符串(也就是摘要信息)。

    StringIO

    StringIO主要用來在內存中寫入字符串及字符串的緩存。其接口和文件操做的接口是一致的,基本全部關於文件的方法均可以用。
    關於文件操做的方法能夠點擊python文件操做查看更多內容。
    示例
    1
    2
    3
    4
    5
    6
    >>> from io import StringIO
    >>> s = StringIO()    #初始化StringIO對象
    >>> s.write('hello world')    #寫入字符串
    11
    >>> s.getvalue()    #獲取實例中的字符串
    'hello world'

stringIO.getvalue()返回StringIO實例中的字符串。
讀取StringIO中的字符串,也可使用文件相似的readreadlinereadlines等方法。網絡

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> s = StringIO()
>>> s.write('hello world')
11
>>> s.write('\n new line')
10
>>> s.seek(0)    #回到文件開頭
0
>>> for line in s:
...     print(line)
...
hello world

 new line

 

BytesIO

StringIO操做只能是str,若是要操做二進制數據,就須要使用BytesIO
BytesIO實現了在內存中讀寫bytes。函數

1
2
3
4
5
6
7
8
9
10
11
12
>>> from io import BytesIO
>>> f = BytesIO()
>>> f.write('中文'.encode('utf-8'))
6
>>> print(f.getvalue())
b'\xe4\xb8\xad\xe6\x96\x87'
>>> f.seek(0)    #回到文件最開頭
0
>>> f.read()    #讀取
b'\xe4\xb8\xad\xe6\x96\x87'
>>> '中文'.encode('utf-8')    #讀取的內容和寫入的對比
b'\xe4\xb8\xad\xe6\x96\x87'

 

此處寫入的內容不是中文字符串,而是通過UTF-8編碼的bytes。

Json

Json(JavaScript Object Notation),它是一種輕量級的數據交換格式。其應用最普遍的是做爲AJAX中web服務器和客戶端的通信的數據格式,如今也經常使用於http請求。

  • 序列化和反序列化
    將對象轉換爲可經過網絡傳輸或能夠存儲到本地磁盤的數據格式(如:XML、JSON或特定數據格式)的過程稱爲序列化;反之則稱爲反序列化。
    python的JSON模塊序列化和反序列化的過程分別叫作:encoding和decoding。
    encoding:把python對象轉換成JSON字符串。
    decoding:把JSON字符串轉換成python對象。
    json模塊提供了下面的方法進行序列化和反序列化操做
    1
    2
    3
    4
    #序列化:將python對象轉換成json字符串
    dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
    #反序列化:將json字符串轉換成python對象
    loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

將序列化後獲得的json數據保存到文件以及直接讀取文件中的json數據進行反序列化操做

1
2
3
4
#序列化:將python對象轉換成json字符串並存儲到文件
dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
#反序列化:讀取指定文件中的json字符串並轉換成python對象
load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

 

json和python數據類型對應關係

  1. python轉換爲json
Python JSON
dict object
list,tuple array
str string
int,float,int- & float-derived Enums number
True true
False false
None null
  1. json轉換爲python
JSON Python
object dict
array list
string str
number(int) int
number(real) float
true True
false False
null None

序列化示例

1
2
3
>>> import json
>>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)})
'{"a": "str", "c": true, "e": 10, "b": 11.1, "d": null, "f": [1, 2, 3], "g": [4, 5, 6]}'

 

sort_keys參數: 表示序列化時是否對dict的key進行排序(dict默認是無序的)

1
2
>>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}, sort_keys=True)
'{"a": "str", "b": 11.1, "c": true, "d": null, "e": 10, "f": [1, 2, 3], "g": [4, 5, 6]}'

 

indent參數: 表示縮進,它可使得數據存儲的格式變得更加優雅、可讀性更強;若是indent是一個非負整數或字符串,則JSON array元素和object成員將會被以相應的縮進級別進行打印輸出;若是indent是0或負數或空字符串,則將只會插入換行,不會有縮進。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>> print(json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}, sort_keys=True, indent=4))
{
    "a": "str",
    "b": 11.1,
    "c": true,
    "d": null,
    "e": 10,
    "f": [
        1,
        2,
        3
    ],
    "g": [
        4,
        5,
        6
    ]
}

 

separators參數: 儘管indent參數可使得數據存儲的格式變得更加優雅、可讀性更強,可是那是經過添加一些冗餘的空白字符進行填充的。當json被用於網絡數據通訊時,應該儘量的減小無用的數據傳輸,這樣能夠節省帶寬並加快數據傳輸速度。json模塊序列化Python對象後獲得的json字符串中的’,’號和’:’號分隔符後默認都會附加一個空白字符,咱們能夠經過separators參數從新指定分隔符,從而去除無用的空白字符。
該參數的值應該是一個tuple(item_separator, key_separator)

  • 若indent是None,其默認值爲(‘, ‘, ‘: ‘)
  • 若indent不爲None,則默認值爲(‘,’, ‘: ‘)
  • 咱們能夠經過爲separator賦值爲(‘,’, ‘:’)來消除空白字符
    1
    2
    3
    4
    >>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)})
    '{"a": "str", "c": true, "e": 10, "b": 11.1, "d": null, "f": [1, 2, 3], "g": [4, 5, 6]}'
    >>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}, separators=(',',':'))
    '{"a":"str","c":true,"e":10,"b":11.1,"d":null,"f":[1,2,3],"g":[4,5,6]}'

ensure_ascii參數: 當該參數的值爲True(默認值)時,輸出中的全部非ASCII字符(好比中文)都會被轉義成’\uXXXX’組成的序列,獲得的結果是一個徹底由ASCII字符組成的str實例。若是咱們想獲得一我的類可讀的輸出結果,須要把ensure_ascii參數的值設置爲False。

1
2
3
4
5
6
7
>>> stu={"name": "小明", "age" : 16}
>>> stu_json = json.dumps(stu)
>>> print(stu_json)
{"name": "\u5c0f\u660e", "age": 16}
>>> stu_json01 = json.dumps(stu, ensure_ascii=False)
>>> print(stu_json01)
{"name": "小明", "age": 16}

 

說明:\u5c0f\u660e是unicode字符對應的內存編碼值,該內存編碼名稱爲」unicode-escape」。能夠經過unicodestr.encode('unicode-escape')decode('unicode-escape')完成unicode字符串和Unicode內存編碼序列進行相互轉換。
反序列化示例

1
2
3
4
>>> json.loads('{"a": "str", "c": true, "b": 11.1, "e": 10, "d": null, "g": [4, 5, 6], "f": [1, 2, 3]}')
{'a': 'str', 'c': True, 'b': 11.1, 'e': 10, 'd': None, 'g': [4, 5, 6], 'f': [1, 2, 3]}
>>> json.loads('{"a":"str","c":true,"b":11.1,"e":10,"d":null,"g":[4,5,6],"f":[1,2,3]}')
{'a': 'str', 'c': True, 'b': 11.1, 'e': 10, 'd': None, 'g': [4, 5, 6], 'f': [1, 2, 3]}

 

load()和dump()

1
2
3
4
5
6
7
8
9
#序列化到文件中
>>> with open('test.json', 'w') as fp:
...     json.dump({'a':'str中國', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}, fp, indent=4)
...
#反序列化文件中的內容
>>> with open('test.json', 'r') as fp:
...     json.load(fp)
...
{'a': 'str中國', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g': [4, 5, 6]}

 

注意:若是試圖使用相同的fp調用dump()函數去序列化多個對象,將會產生一個無效的JSON文件。也就是說對於一個fd只能調用一次dump()
更多更詳細的內容能夠點擊JSON encoder and decoder查看官網內容。

相關文章
相關標籤/搜索