Heim  >  Fragen und Antworten  >  Hauptteil

如何找到Python的hashlib的实现(见截图)?

1 在hashlib.py中貌似找不到md5()这些东西
2 hashlib.py也没有import什么东西


怪我咯怪我咯2742 Tage vor1026

Antworte allen(1)Ich werde antworten

  • ringa_lee

    ringa_lee2017-04-17 17:37:01

    hashlib里因为会有类似Crypto的数字计算,如果纯用python做的话,速度很慢,达不到要求,因此这个具体的实现是放在_hashlib.pyd,对于Python2.7, 路径位于C:\Python27\DLLs_hashlib.pyd,采用C实现的这个动态库里

    import hashlib
    print help(hashlib.md5)
    
    import _hashlib
    print help(_hashlib.openssl_md5)
    
    
    # 生成的MD5值一样
    S = "this is a demo for md5"
    assert hashlib.md5(S).hexdigest() == _hashlib.openssl_md5(S).hexdigest()
    

    加载过程为:

    try:
        import _hashlib
        new = __hash_new
        __get_hash = __get_openssl_constructor
        algorithms_available = algorithms_available.union(
            _hashlib.openssl_md_meth_names)
    except ImportError:
        new = __py_new
        __get_hash = __get_builtin_constructor
    
    for __func_name in __always_supported:
        # try them all, some may not work due to the OpenSSL
        # version not supporting that algorithm.
        try:
            globals()[__func_name] = __get_hash(__func_name)
        except ValueError:
            import logging
            logging.exception('code for hash %s was not found.', __func_name)
    
    
    try:
        # OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA
        from _hashlib import pbkdf2_hmac
    except ImportError:
        import binascii
        import struct
    
        _trans_5C = b"".join(chr(x ^ 0x5C) for x in range(256))
        _trans_36 = b"".join(chr(x ^ 0x36) for x in range(256))
    
        def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None):
            """Password based key derivation function 2 (PKCS #5 v2.0)
    
            This Python implementations based on the hmac module about as fast
            as OpenSSL's PKCS5_PBKDF2_HMAC for short passwords and much faster
            for long passwords.
            """
            if not isinstance(hash_name, str):
                raise TypeError(hash_name)
    
            if not isinstance(password, (bytes, bytearray)):
                password = bytes(buffer(password))
            if not isinstance(salt, (bytes, bytearray)):
                salt = bytes(buffer(salt))
    
            # Fast inline HMAC implementation
            inner = new(hash_name)
            outer = new(hash_name)
            blocksize = getattr(inner, 'block_size', 64)
            if len(password) > blocksize:
                password = new(hash_name, password).digest()
            password = password + b'\x00' * (blocksize - len(password))
            inner.update(password.translate(_trans_36))
            outer.update(password.translate(_trans_5C))
    
            def prf(msg, inner=inner, outer=outer):
                # PBKDF2_HMAC uses the password as key. We can re-use the same
                # digest objects and just update copies to skip initialization.
                icpy = inner.copy()
                ocpy = outer.copy()
                icpy.update(msg)
                ocpy.update(icpy.digest())
                return ocpy.digest()
    
            if iterations < 1:
                raise ValueError(iterations)
            if dklen is None:
                dklen = outer.digest_size
            if dklen < 1:
                raise ValueError(dklen)
    
            hex_format_string = "%%0%ix" % (new(hash_name).digest_size * 2)
    
            dkey = b''
            loop = 1
            while len(dkey) < dklen:
                prev = prf(salt + struct.pack(b'>I', loop))
                rkey = int(binascii.hexlify(prev), 16)
                for i in xrange(iterations - 1):
                    prev = prf(prev)
                    rkey ^= int(binascii.hexlify(prev), 16)
                loop += 1
                dkey += binascii.unhexlify(hex_format_string % rkey)
    
            return dkey[:dklen]
    
    # Cleanup locals()
    del __always_supported, __func_name, __get_hash
    del __py_new, __hash_new, __get_openssl_constructor
    

    Antwort
    0
  • StornierenAntwort