o
    :Fd?                     @   s(  d Z ddlZddlZddlZeZg dZg Zejd dk rFe	dZ
e	dZe	dZe	dZe	d	Ze	d
Ze	dZeD ]	Zee	e q;ndZ
dZdZdZdZdZdZeD ]Zee	ed qVdd Zdd Zdd Zdd Zdd Zdd Zdd  ZG d!d" d"Zd#Zd(d$d%Zd(d&d'ZdS ))a\  
This is an implementation of the MD5 hash function, as specified by
RFC 1321, in pure Python.

This code is a modified version of
https://github.com/doegox/python-cryptoplus/blob/master/src/CryptoPlus/Hash/pymd5.py
by Dinu C. Gherman.  It supports python 2 and 3.

pymd5 has these methods:
 - update(arg): Update the md5 object with the string arg. Repeated calls
                are equivalent to a single call with the concatenation of all
                the arguments.
 - digest():    Return the digest of the strings passed to the update() method
                so far. This may contain non-ASCII characters, including
                NUL bytes.
 - hexdigest(): Like digest() except the digest is returned as a string of
                double length, containing only hexadecimal digits.

For example, to obtain the hexdigest of 'Hello World':
    >>> import pymd5
    >>> m = pymd5.md5()
    >>> m.update(b"Hello World")
    >>> m.hexdigest()
More condensed:
    >>> pymd5.md5(b"Hello World").hexdigest()
Shoud give the same result as:
    >>> import hashlib
    >>> hashlib.md5(b"Hello World").hexdigest()

    N)@Z0xD76AA478LZ0xE8C7B756LZ0x242070DBLZ0xC1BDCEEELZ0xF57C0FAFLZ0x4787C62ALZ0xA8304613LZ0xFD469501LZ0x698098D8LZ0x8B44F7AFLZ0xFFFF5BB1LZ0x895CD7BELZ0x6B901122LZ0xFD987193LZ0xA679438ELZ0x49B40821LZ0xF61E2562LZ0xC040B340LZ0x265E5A51LZ0xE9B6C7AALZ0xD62F105DLZ0x02441453LZ0xD8A1E681LZ0xE7D3FBC8LZ0x21E1CDE6LZ0xC33707D6LZ0xF4D50D87LZ0x455A14EDLZ0xA9E3E905LZ0xFCEFA3F8LZ0x676F02D9LZ0x8D2A4C8ALZ0xFFFA3942LZ0x8771F681LZ0x6D9D6122LZ0xFDE5380CLZ0xA4BEEA44LZ0x4BDECFA9LZ0xF6BB4B60LZ0xBEBFBC70LZ0x289B7EC6LZ0xEAA127FALZ0xD4EF3085LZ0x04881D05LZ0xD9D4D039LZ0xE6DB99E5LZ0x1FA27CF8LZ0xC4AC5665LZ0xF4292244LZ0x432AFF97LZ0xAB9423A7LZ0xFC93A039LZ0x655B59C3LZ0x8F0CCC92LZ0xFFEFF47DLZ0x85845DD1LZ0x6FA87E4FLZ0xFE2CE6E0LZ0xA3014314LZ0x4E0811A1LZ0xF7537E82LZ0xBD3AF235LZ0x2AD7D2BBLZ0xEB86D391L   Z0LZ0xffffffffLZ0x3FLZ0x67452301LZ0xefcdab89LZ0x98badcfeLZ0x10325476Ll    ?   i#Egl   +_ l   \u1 ivT2Lc           	      C   s  t t| d }tg| }d}d}||k rtjd dk rItt| | }tt| |d  d> }tt| |d  d> }tt| |d  d> }nc| | }t|trXt| | }t| |d  trlt| |d  d> }n| |d  d> }t| |d  trt| |d  d> }n| |d  d> }t| |d  trt| |d  d> }n| |d  d> }||B |B |B ||< |d }|d }||k s|S )	z4Transform a list of characters into a list of longs.   r   r                  )	intlen	long_zerosysversion_infolongord
isinstancestr)	listZimaxZhljiZb0Zb1Zb2Zb3 r   6usr/lib/python3.10/site-packages/oci_cli/util/pymd5.py_bytelist2longW   s6   

r   c                 C   s   | |> | d| ? B S )z)Rotate x (32 bit) left n bits circularly.    r   )xnr   r   r   _rotateLeft|   s   r   c                 C   s   | |@ |  |@ B S Nr   r   yzr   r   r   F      r"   c                 C   s   | |@ || @ B S r   r   r   r   r   r   G   r#   r$   c                 C   s   | |A |A S r   r   r   r   r   r   H   s   r%   c                 C   s   || | B A S r   r   r   r   r   r   I   s   r&   c           	      C   sR   t }|| | ||| }|| }|| }|t@ }t||}|t@ }|| }|t@ S )zWrapper for call distribution to functions F, G, H and I.
    This replaces functions FF, GG, HH and II from "Appl. Crypto."
    Rotation is separate from addition to prevent recomputation
    (now summed-up in one function).
    )r   	ffffffffLr   )	funcabcdr   sZacresr   r   r   XX   s   
r/   c                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )MD5Typez:An implementation of the MD5 hash function in pure Python.c                 C   s"   t | _ddg| _g | _|   dS )zInitialisation.r   N)r   lengthcountinputinitselfr   r   r   __init__   s   
zMD5Type.__init__c                 C   s2   t | _ddg| _g | _t| _t| _t| _	t
| _dS )z9Initialize the message-digest and set all fields to zero.r   N)r   r1   r2   r3   	constantAA	constantBB	constantCC	constantDDr5   r   r   r   r4      s   

zMD5Type.initc              
   C   s(  | j | j| j| jf \}}}}\}}}}	d\}
}}}tt|||||d |
td }tt|||||d |td }tt|||||d |td }tt|||||d |td }tt|||||d |
td }tt|||||d |td }tt|||||d |td }tt|||||d	 |td	 }tt|||||d
 |
td
 }tt|||||d |td }tt|||||d |td }tt|||||d |td }tt|||||d |
td }tt|||||d |td }tt|||||d |td }tt|||||d |td }d\}}}}tt|||||d |td }tt|||||d |td }tt|||||d |td }tt|||||d |td }tt|||||d |td }tt|||||d |td }tt|||||d |td }tt|||||d |td }tt|||||d |td }tt|||||d |td }tt|||||d |td }tt|||||d
 |td }tt|||||d |td }tt|||||d |td  }tt|||||d	 |td! }tt|||||d |td" }d#\}}}}tt|||||d |td$ }tt|||||d
 |td% }tt|||||d |td& }tt|||||d |td' }tt|||||d |td( }tt|||||d |td) }tt|||||d	 |td* }tt|||||d |td+ }tt|||||d |td, }tt|||||d |td- }tt|||||d |td. }tt|||||d |td/ }tt|||||d |td0 }tt|||||d |td1 }tt|||||d |td2 }tt|||||d |td3 }d4\}}}}tt	|||||d |td5 }tt	|||||d	 |td6 }tt	|||||d |td7 }tt	|||||d |td8 }tt	|||||d |td9 }tt	|||||d |td: }tt	|||||d |td; }tt	|||||d |td< }tt	|||||d
 |td= }tt	|||||d |td> }tt	|||||d |td? }tt	|||||d |td@ }tt	|||||d |tdA }tt	|||||d |tdB }tt	|||||d |tdC }tt	|||||d |tdD }|| t
@ }|| t
@ }|| t
@ }|	| t
@ }	||||	f\| _ | _| _| _dES )FzBasic MD5 step transforming the digest based on the input.
        Note that if the Mysterious Constants are arranged backwards
        in little-endian order and decrypted with the DES they produce
        OCCULT MESSAGES!
        )            r   r   r   r   r         r@   r   	   
      rA            )rD   rF   rJ      r	   rB         rL      rC      r
                        )r   rH   r	   rP   r   !   "   #   $   %   &   '   (   )   *   +   ,   -   .   /   )rE   rG   rK   rO   0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   r   N)r9   r;   r=   r?   r/   r"   hex_constantsr$   r%   r&   r'   )r6   inpr)   r*   r+   r,   r9   r;   r=   r?   ZS11ZS12ZS13ZS14ZS21ZS22ZS23ZS24ZS31ZS32ZS33ZS34ZS41ZS42ZS43ZS44r   r   r   
_transform   s   ( zMD5Type._transformc                 C   s6  t jd dk rtt|}nt|}| jd d? t@ }| jd |d>  | jd< | jd |d> k r:| jd d | jd< | jd |d?  | jd< d| }||krt|d| | j|d< | t	| j |}|d |k r| t	t|||d   |d }|d |k skt||| | _dS d}| jt| | _dS )a<  Add to the current message.
        Update the md5 object with the string arg. Repeated calls
        are equivalent to a single call with the concatenation of all
        the arguments, i.e. m.update(a); m.update(b) is equivalent
        to m.update(a+b).
        The hash is immediately calculated for all full blocks. The final
        calculation is made in digest(). This allows us to keep an
        intermediate value for the hash, so that we only need to make
        minimal recalculation if we call update() to add moredata to
        the hashed string.
        r   r   r   rU   @   Nr   )
r   r   r   r   r2   x3FLr   r3   rx   r   )r6   ZinBufZleninBufindexZpartLenr   r   r   r   update)  s(   zMD5Type.updatec                 C   s   | j }| j}| j}| j}g | j }g | j }| jd d? t@ }|dk r(d| }nd| }dgdgd  }	| |	d|  t| jdd | }
| 	|
 t
d	| j | j| j| j}|| _ || _|| _|| _|| _|| _|S )
zTerminate the message-digest computation and return digest.
        Return the digest of the strings passed to the update()
        method so far. This is a 16-byte string which may contain
        non-ASCII characters, including null bytes.
        r   r   ro   x       r   Nz<IIII)r9   r;   r=   r?   r3   r2   rz   r|   r   rx   structpack)r6   r9   r;   r=   r?   r3   r2   r{   ZpadLenpaddingbitsdigestr   r   r   r   S  s,   



zMD5Type.digestc                 C   sn   t jd dk rddd |  D S g }|  D ]}t|tr%t|}n|}|| qddd |D S )a  Terminate and return digest in HEX form.
        Like digest() except the digest is returned as a string of
        length 32, containing only hexadecimal digits. This may be
        used to exchange the value safely in email or other non-
        binary environments.
        r   r    c                 S   s   g | ]}d t | qS z%02x)r   .0r+   r   r   r   
<listcomp>  s    z%MD5Type.hexdigest.<locals>.<listcomp>c                 S   s   g | ]}d | qS r   r   r   r   r   r   r     s    )r   r   joinr   r   r   r   append)r6   r   r+   valr   r   r   	hexdigest|  s   

zMD5Type.hexdigestc                 C   sV   	 |  }| j|_g | jdd  |_g | j |_| j|_| j|_| j|_| j	|_	|S )zReturn a clone object.
        Return a copy ('clone') of the md5 object. This can be used
        to efficiently compute the digests of strings that share
        a common initial substring.
        r   N)
copydeepcopy	__class__r1   r2   r3   r9   r;   r=   r?   )r6   cloner   r   r   r     s   zMD5Type.copyN)__name__
__module____qualname____doc__r7   r4   rx   r|   r   r   r   r   r   r   r   r0      s    ]*)r0   r	   c                 C   s   t  }| r
||  |S )z`Return a new md5 crypto object.
    If arg is present, the method call update(arg) is made.
    )r0   r|   )argZcryptor   r   r   new  s   
r   c                 C   s   t | S )zsSame as new().
    For backward compatibility reasons, this is an alternative
    name for the new() function.
    )r   )r   r   r   r   md5  s   r   r   )r   r   r   r   typeZ__metaclass__Zhex_constant_stringsrv   r   evalr   r'   rz   r8   r:   r<   r>   Zhsr   rstripr   r   r"   r$   r%   r&   r/   r0   digest_sizer   r   r   r   r   r   <module>   sN   % z
