搜尋

首頁  >  問答  >  主體

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

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


怪我咯怪我咯2859 天前1091

全部回覆(1)我來回復

  • ringa_lee

    ringa_lee2017-04-17 17:37:01

    hashlib裡因為會有類似Crypto的數字計算,如果純用python做的話,速度很慢,達不到要求,因此這個具體的實現是放在_hashlib.pyd,對於Python2.7, 路徑位於C: Python27DLLs_hashlib.pyd,採用C實作的這個動態函式庫裡

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    <code>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()

    </code>

    加載過程為:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    <code>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

    </code>

    回覆
    0
  • 取消回覆