
                           d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlZddlZddlm	Z	 ddlm
Z
 dd	lmZ dd
lmZ ddlmZ  G d dej                         Zd Zd Zd ZddZ	 	 d	 	 	 	 	 ddZ	 d	 	 	 	 	 ddZddZd Zd Zd Zd Zy)z'Hashing utilities for storage commands.    )absolute_import)annotations)division)unicode_literalsN)errors)fast_crc32c_util)
installers)files)hashingc                      e Zd ZdZdZdZy)HashAlgorithmz&Algorithms available for hashing data.md5crc32cN)__name__
__module____qualname____doc__MD5CRC32C     3lib/googlecloudsdk/command_lib/storage/hash_util.pyr   r       s    .#&r   r   c                L    t        j                  |       j                  d      S )z.Takes bytes and returns base64-encoded string.utf-8)encoding)base64	b64encodedecode)
hash_bytess    r   get_base64_stringr    '   s!    			*	%	,	,g	,	>>r   c                N    | j                  d      }t        j                  |      S )z.Takes base64-encoded string and returns bytes.r   )encoder   	b64decode)hash_stringr   s     r   get_bytes_from_base64_stringr%   ,   s#    !!'**			*	%%r   c                4    t        | j                               S )zATakes hashlib object and returns base64-encoded digest as string.)r    digest)hash_objects    r   get_base64_hash_digest_stringr)   2   s    	;--/	00r   c                    | t         j                  k(  rt        j                         S | t         j                  k(  rt        j                         S y)z3Returns a hash object for the given hash algorithm.N)r   r   r   get_md5r   r   
get_crc32c)hash_algorithms    r   get_hash_objectr.   7   s=    }(((??}+++&&((	r   c                    t        |t        j                        r#|dn|}|dn||z
  }|j                  | ||       |S )z?Returns the hash for the given path and deferred crc32c object.r   )offsetlength)
isinstancer   DeferredCrc32csum_file)pathr(   startstopr0   r1   s         r   _get_hash_for_deferred_crc32cr8   @   sJ     -<<=-QUF,QD6MFfV<	r   c                    t        |      }|yt        |t        j                        rt	        | |||      S |j                  |       |S )ag  Returns the hash object for the given data chunk or file.

  For MD5 and FastCRC32C, this function will return a hash object after
  hashing the given data chunk. For DeferredCRC32C, this function will return
  the deferred hash object from the given file path.

  Args:
    path (str): The file path.
    data (bytes): The data chunk to hash.
    hash_algorithm (HashAlgorithm): The algorithm to use for hashing.
    start (int|None): Optional byte index to start hashing from.
    stop (int|None): Optional byte index to stop hashing at.

  Returns:
    A hash object or None if the algorithm is not supported.
  N)r.   r2   r   r3   r8   update)r5   datar-   r6   r7   r(   s         r    get_hash_from_data_chunk_or_filer<   N   sM    &  /+-<<=({E4HHT	r   c                >   t        |      }|yt        |t        j                        rt	        | |||      S t        j                  |       5 }|r|j                  |       	 |r|j                         |k\  rn|$|j                         t        j                  z   |k  rt        j                  }n||j                         z
  }|j                  |      }|sn3t        |t              r|j                  d      }|j                  |       ddd       |S # 1 sw Y   |S xY w)aW  Reads file and returns its hash object.

  core.util.files.Checksum does similar things but is different enough to merit
  this function. The primary differences are that this function:
  -Uses a FIPS-safe MD5 object.
  -Accomodates gcloud_crc32c, which uses a Go binary for hashing.
  -Supports start and end index to set byte range for hashing.

  Args:
    path (str): File to read.
    hash_algorithm (HashAlgorithm): Algorithm to hash file with.
    start (int|None): Byte index to start hashing at.
    stop (int|None): Stop hashing at this byte index.

  Returns:
    Hash object for file.
  Nr   )r.   r2   r   r3   r8   r
   BinaryFileReaderseektellr	   WRITE_BUFFER_SIZEreadstrr"   r:   )r5   r-   r6   r7   r(   streambytes_to_readr;   s           r   get_hash_from_filerF   j   s   $  /+-<<=({E4HHd#vkk%
	&++-4' 
)E)EEL"44v{{},[['d	D#	{{7#%  $. 
/ $. 
s   B<DDc                Z    ||k7  r&t        j                  dj                  |||             y)a	  Confirms hashes match for copied objects.

  Args:
    object_path (str): URL of object being validated.
    source_hash (str): Hash of source object.
    destination_hash (str): Hash of destination object.

  Raises:
    HashMismatchError: Hashes are not equal.
  z@Source hash {} does not match destination hash {} for object {}.N)r   HashMismatchErrorformat)object_pathsource_hashdestination_hashs      r   validate_object_hashes_matchrM      s;     $$

"
"	 &.>LN N %r   c                P    | j                         D ]  }|j                  |        y)z?Updates every hash object with new data in a dict of digesters.N)valuesr:   )	digestersr;   r(   s      r   update_digestersrQ      s#    %%'kt (r   c                D    i }| D ]  }| |   j                         ||<    |S )zBReturns copy of provided digesters since deepcopying doesn't work.)copy)rP   resultr-   s      r   copy_digestersrU      s.    &!n&~6;;=F> "	-r   c                    | D ]y  }|t         j                  u rt        j                         | |<   -|t         j                  u rt        j                         | |<   Wt        j                  dj                  |             y)z>Clears the data from every hash object in a dict of digesters.z-Unknown hash algorithm found in digesters: {}N)
r   r   r   r+   r   r   r,   r   ErrorrI   )rP   r-   s     r   reset_digestersrX      sk    !n***")//"3i	=//	/"2"="="?iLL
9
@
@
P  "r   )r-   r   )NN)r5   rC   r(   zfast_crc32c_util.DeferredCrc32creturnz
int | None)r5   rC   r;   bytesr-   r   )r   
__future__r   r   r   r   r   enum"googlecloudsdk.command_lib.storager   r   googlecloudsdk.core.updaterr	   googlecloudsdk.core.utilr
   r   Enumr   r    r%   r)   r.   r8   r<   rF   rM   rQ   rU   rX   r   r   r   <module>ra      s    . & "  '   5 ? 2 * ,DII ?
&1
 		
0
  MQ
,980fN"
r   