• Python学习之旅(二十七)


    Python基础知识(26):常用内建模块(Ⅱ)

    1、hashlib

    Python的hashlib提供了常见的摘要算法,如MD5,SHA1等

    摘要算法又称哈希算法、散列算法。

    (1)它通过一个函数,把任意长度的数据转换为一个长度固定的数据串(通常用16进制的字符串表示)

    (2)摘要算法就是通过摘要函数f()对任意长度的数据data计算出固定长度的摘要digest,目的是为了发现原始数据是否被人篡改过

    MD5

    MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示

    import hashlib
    md5 = hashlib.md5()
    md5.update('How to use md5 in python hashlib'.encode('utf-8'))
    print(md5.hexdigest())
    
    结果:
    8b6e4d30c576051f3ca4be97e8314d15

    SHA1

    import hashlib
    sha1 = hashlib.sha1()
    sha1.update('How to use SHA1 in python hashlib'.encode('utf-8'))
    print(sha1.hexdigest())
    
    结果:
    8a4dbc942c7ff059115b56645ab484c4188bd5ce

    SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示

    比SHA1更安全的算法是SHA256和SHA512,不过越安全的算法不仅越慢,而且摘要长度更长

    摘要算法的应用

    用户登录网站的用户名和口令都存储数据库,口令使用摘要算法进行加密

    当用户登录时,首先计算用户输入的明文口令的MD5,然后和数据库存储的MD5对比,如果一致,说明口令输入正确,如果不一致,口令肯定错误

    要确保存储的用户口令不是那些已经被计算出来的常用口令的MD5,这一方法通过对原始口令加一个复杂字符串来实现,俗称“加盐

    经过Salt处理的MD5口令,只要Salt不被黑客知道,即使用户输入简单口令,也很难通过MD5反推明文口令

    设计一个验证用户登录的函数,根据用户输入的口令是否正确

    import hashlib
    db = {
        'michael': 'e10adc3949ba59abbe56e057f20f883e',
        'bob': '878ef96e86145580c38c87f0410ad153',
        'alice': '99b1c2188db85afee403b1536010c2c9'
    }
    def calc_md5(password):
        md5 = hashlib.md5()
        md5.update(password.encode('utf-8'))
        return md5.hexdigest()
    def login(user, password):
        md5 = calc_md5(password)
        if user in db and md5 in db.get(user):
            print('Welcome')
        else:
            print('Incorrect username or password')
    
    login('michael', '123456')
    login('bob', 'abc999')
    login('alice', 'alice2008')
    login('michael', '1234567')
    login('bob', '123456')
    login('alice', 'Alice2008')
    
    结果:
    Welcome
    Welcome
    Welcome
    Incorrect username or password
    Incorrect username or password
    Incorrect username or password

     

    HMAC是密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出

    Python自带的hmac模块实现了标准的Hmac算法,它利用一个key对message计算“杂凑”后的hash,使用hmac算法比标准hash算法更安全,因为针对相同的message,不同的key会产生不同的hash

    import hmac
    message = b'Hello,world!'
    key = b'secret'
    h = hmac.new(key, message, digestmod='MD5')
    print(h.hexdigest())
    
    结果:
    21db988f124ebc9fade5492afb9df52d

    3、itertools

    Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数

    (1)count

    count()会创建一个无限的迭代器,所以上述代码会打印出自然数序列,根本停不下来,只能按Ctrl+C退出

    import itertools
    natuals = itertools.count(1)
    for i in natuals:
        print(i)

    (2)cycle

    cycle()会把传入的一个序列无限重复下去

    import itertools
    cs = itertools.cycle('ABC')
    for i in cs:
        print(i)

    (3)repeat

    repeat()负责把一个元素无限重复下去,不过如果提供第二个参数就可以限定重复次数

    import itertools
    ns = itertools.repeat('A', 3)
    for i in ns:
        print(i)
    
    结果:
    A
    A
    A

    (4)takewhile

    无限序列只有在for迭代时才会无限地迭代下去,如果只是创建了一个迭代对象,它不会事先把无限个元素生成出来,事实上也不可能在内存中创建无限多个元素

    无限序列虽然可以无限迭代下去,但是通常我们会通过takewhile()等函数根据条件判断来截取出一个有限的序列

    import itertools
    natuals = itertools.count(1)
    ns = itertools.takewhile(lambda x:x<=10, natuals)
    for i in ns:
        print(i)
    
    结果:
    1
    ...
    10

    (5)chain

    chain()可以把一组迭代对象串联起来,形成一个更大的迭代器

    import itertools
    for c in itertools.chain('ABC','123'):
        print(c)
    
    结果:
    A
    B
    C
    1
    2
    3

    (6)groupby

    groupby()把迭代器中相邻的重复元素挑出来放在一起

    实际上挑选规则是通过函数完成的,只要作用于函数的两个元素返回的值相等,这两个元素就被认为是在一组的,而函数返回值作为组的key

    如果我们要忽略大小写分组,就可以让元素'A''a'都返回相同的key

    import itertools
    for key,group in itertools.groupby('monent'):
        print(key,list(group))
    
    for key,group in itertools.groupby('AAaaaBBBbbccC', lambda c:c.upper()):
        print(key,list(group))
    
    结果:
    m ['m']
    o ['o']
    n ['n']
    e ['e']
    n ['n']
    t ['t']
    A ['A', 'A', 'a', 'a', 'a']
    B ['B', 'B', 'B', 'b', 'b']
    C ['c', 'c', 'C']

    4、contextlib

    在Python中,读写文件这样的资源要特别注意,必须在使用完毕后正确关闭它们。正确关闭文件资源的一个方法是使用try...finally

    try...finally非常繁琐,使用Python的with语句更加方便

    #try..finally...
    try:
        f = open('/path/to/file', 'r')
        f.read()
    finally:
        if f:
            f.close()
    
    #with
    with open('/path/to/file', 'r') as f:
        f.read()

    实现上下文管理是通过__enter____exit__这两个方法实现的,任何对象只要正确实现了上下文管理,就可以用于with语句

    @contextmanager

    编写__enter____exit__仍然很繁琐,因此Python的标准库contextlib提供了更简单的写法

    @closing

    如果一个对象没有实现上下文,我们就不能把它用于with语句。这个时候,可以用closing()来把该对象变为上下文对象

  • 相关阅读:
    程序员的困境
    linux中获取系统时间 gettimeofday函数
    Vim 模式及常用命令整理
    使用stringstream进行类型转换与字符串分割
    EasyNet开源项目计划
    用Akka构建一个简易的分布式文件系统
    SolrCloud攻略
    EasyNet.Solr 4.4.0发布及例子
    axis2调用webservice
    Oracle常用函数2查询
  • 原文地址:https://www.cnblogs.com/finsomway/p/10089493.html
Copyright © 2020-2023  润新知