美文网首页
哈希算法

哈希算法

作者: pubalabala | 来源:发表于2018-11-28 15:37 被阅读0次
    哈希算法 - 哈希摘要 - 数字签名/数字指纹 - 防篡改/保护敏感信息
    • 哈希算法是一个单向运算的函数(单向哈希函数)

    • 通过哈希算法可以将对象计算出哈希摘要,但是哈希摘要无法还原出原来的对象

    • Martin Fowler - 代码有很多种坏味道,重复是最坏的一种
      当代码已经充斥着各种坏味道的时候就需要对代码进行重构(refactor)
      策略模式

    import hashlib
    
    
    class StreamHasher(object):
    
        def __init__(self, algorithm='md5', size=4096):
            self.size = size
            alg = algorithm.lower()
            if alg == 'md5':
                self.hasher = hashlib.md5()
            elif alg == 'sha1':
                self.hasher = hashlib.sha1()
            elif alg == 'sha256':
                self.hasher = hashlib.sha256()
            elif alg == 'sha512':
                self.hasher = hashlib.sha512()
            else:
                raise  ValueError('不支持指定的哈希算法')
    
        def to_md5_digest(self, stream):
            '''生成MD5摘要'''
            for buf in iter(lambda: stream.read(self.size), b''):
                self.hasher.update(buf)
            return self.hasher.hexdigest()
    
        def __call__(self, stream):
            return self.to_md5_digest(stream)
    
    加密解密
    • 对称加密- 加密和揭秘使用同一个密钥 - DES(过时)/AES
    • 非对称加密 - 加密和解密使用不同的密钥 - RSA
    • pip install pycrypto
    编码和解码 - 将内存中的二进制数据处理成其他的形式 - BASE64
    • BASE64 - 用64个字符(a-zA-Z0-9/+)表示所有的二进制数据
      110000   111010    11100   110101
    00110000 00111010 00011100 00110101
    
    魔术方法
    • 如果该自定义对象要放到set种那么需要重写两个魔术方法
      • hash - 计算出对相对应的哈希码
      • eq - '=='运算符对应的方法用来比较两个对象是否相同
      • 重写eq的前提是必须先重写hash
      • 如果两个对象eq的结果为True那么必须有相同的哈希码
      • 如果该两个对象哈希码相同但是eq的结果可能时True也可能时False
      • 相同对象必须有相同的哈希码, 不同的对象可能会产生相同的哈希码(哈希碰撞)
      • 哈希存储(散列存储) - 通过计算对象的哈希码决定如何存储对象
    • 哈希算法 - MD5/SHA1/SHA256/SHA512
    class Student(object):
    
        def __init__(self, stuid, name, gender):
            self.stuid = stuid
            self.name = name
            self.gender = gender
    
        def __hash__(self):
            return self.stuid
    
        def __eq__(self, other):
            # return self.stuid == other.stuid
            return self.stuid == other.stuid and self.name == other.name
    
        def __enter__(self):
            return self
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            # 当类中的方法要需要使用上下文语法时, 如 with create_studetn() as stu, 必须先定义__enter__和__exit__两个方法来对方法的开始和结束进行处理, 如数据库的开启和关闭.
            pass
    
        def create_student(self):
            pass
    
    整体代码
    import hashlib
    
    
    class StreamHasher(object):
    
        def __init__(self, algorithm='md5', size=4096):
            self.size = size
            alg = algorithm.lower()
            if alg == 'md5':
                self.hasher = hashlib.md5()
            elif alg == 'sha1':
                self.hasher = hashlib.sha1()
            elif alg == 'sha256':
                self.hasher = hashlib.sha256()
            elif alg == 'sha512':
                self.hasher = hashlib.sha512()
            else:
                raise  ValueError('不支持指定的哈希算法')
    
        def to_md5_digest(self, stream):
            '''生成MD5摘要'''
            for buf in iter(lambda: stream.read(self.size), b''):
                self.hasher.update(buf)
            return self.hasher.hexdigest()
    
        def __call__(self, stream):
            return self.to_md5_digest(stream)
    
    
    class Student(object):
    
        def __init__(self, stuid, name, gender):
            self.stuid = stuid
            self.name = name
            self.gender = gender
    
        def __hash__(self):
            return self.stuid
    
        def __eq__(self, other):
            # return self.stuid == other.stuid
            return self.stuid == other.stuid and self.name == other.name
    
        def __enter__(self):
            return self
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            # 当类中的方法要需要使用上下文语法时, 如 with create_studetn() as stu, 必须先定义__enter__和__exit__两个方法来对方法的开始和结束进行处理, 如数据库的开启和关闭.
            pass
    
        def create_student(self):
            pass
    
    
    
    def main():
        # with open('C:\\Users\\ap-le\Desktop\\PokerGame.py', 'rb') as stream:
        #     # 分流读入文件, 节省内存
        #     buf = stream.read(4096)
        #     while buf:
        #         hasher.update(stream.read())
        #         buf = stream.read(4096)
        # print(hasher.hexdigest())
        #
        # # 使用迭代对象读入文件
        # with open('C:\\Users\\ap-le\Desktop\\PokerGame.py', 'rb') as stream:
        #     for buf in iter(lambda: stream.read(4096), b''):
        #         hasher.update(buf)
        # print(hasher.hexdigest())
        # sh = StreamHasher()
        # sh = StreamHasher('sha1')
        # sh = StreamHasher('sha256')
        sh = StreamHasher('sha512')
        with open('C:\\Users\\ap-le\Desktop\\PokerGame.py', 'rb') as stream:
            print(sh.to_md5_digest(stream))
            print(sh(stream))
    
        print('-'*50)
        set1 = {
            Student(1001, 'Jefferson', True),
            Student(1001, 'Jefferson', True),
            Student(1001, '王大锤', True)
        }
        print(len(set1))
        print(set1)
    
    
    if __name__ == '__main__':
        main()
    

    相关文章

      网友评论

          本文标题:哈希算法

          本文链接:https://www.haomeiwen.com/subject/uztzqqtx.html