
    T                       S r SSKJr  SSKrSSKrSSKrSSKJr  SSKJr  SSK	J
r
  SSKJr  SSKJr  SS	KJr   " S
 S\R                   5      rS rS rS rSS jr  S     SS jjr S     SS jjrSS jrS rS rS rS rg)z'Hashing utilities for storage commands.    )annotationsN)errors)fast_crc32c_util)log)
installers)files)hashingc                       \ rS rSrSrSrSrSrg)HashAlgorithm   z&Algorithms available for hashing data.md5crc32c N)__name__
__module____qualname____firstlineno____doc__MD5CRC32C__static_attributes__r       3lib/googlecloudsdk/command_lib/storage/hash_util.pyr   r      s    .#&r   r   c                H    [         R                  " U 5      R                  SS9$ )z.Takes bytes and returns base64-encoded string.utf-8)encoding)base64	b64encodedecode)
hash_bytess    r   get_base64_stringr!   &   s!    			*	%	,	,g	,	>>r   c                P    U R                  S5      n[        R                  " U5      $ )z.Takes base64-encoded string and returns bytes.r   )encoder   	b64decode)hash_stringr    s     r   get_bytes_from_base64_stringr&   +   s#    !!'**			*	%%r   c                4    [        U R                  5       5      $ )zATakes hashlib object and returns base64-encoded digest as string.)r!   digest)hash_objects    r   get_base64_hash_digest_stringr*   1   s    	;--/	00r   c                    U [         R                  :X  a  [        R                  " 5       $ U [         R                  :X  a  [
        R                  " 5       $ g)z3Returns a hash object for the given hash algorithm.N)r   r   r	   get_md5r   r   
get_crc32c)hash_algorithms    r   get_hash_objectr/   6   s=    }(((??}+++&&((	r   c                    [        U[        R                  5      (       a   Uc  SOUnUc  SOX4-
  nUR                  XUS9  U$ )z?Returns the hash for the given path and deferred crc32c object.r   )offsetlength)
isinstancer   DeferredCrc32csum_file)pathr)   startstopr1   r2   s         r   _get_hash_for_deferred_crc32cr9   ?   sI     -<<==-QUF,QDMFV<	r   c                    [        U5      nUc  g[        U[        R                  5      (       a  [	        XX45      $ UR                  U5        U$ )aO  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/   r3   r   r4   r9   update)r6   datar.   r7   r8   r)   s         r    get_hash_from_data_chunk_or_filer=   M   sL    &  /+-<<==(EHHT	r   c                   [        U5      nUc  g[        U[        R                  5      (       a  [	        XX#5      $ [
        R                  " U 5       nU(       a  UR                  U5         U(       a  UR                  5       U:  a  OUb%  UR                  5       [        R                  -   U:  a  [        R                  nOX5R                  5       -
  nUR                  U5      nU(       d  O9[        U[        5      (       a  UR                  S5      nUR                  U5        M  SSS5        U$ ! , (       d  f       U$ = f)a=  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/   r3   r   r4   r9   r   BinaryFileReaderseektellr   WRITE_BUFFER_SIZEreadstrr#   r;   )r6   r.   r7   r8   r)   streambytes_to_readr<   s           r   get_hash_from_filerG   i   s   $  /+-<<==(EHHd#vkk%
	&++-4' 
)E)EEL"44{{},[['d	D#		{{7#%  $. 
/ $#. 
s   CD..
D=c           
        X:w  a   [        U5      n[        U5      n[        R                  " SU U[        R                  " U5      R                  S5      U[        R                  " U5      R                  S5      5        [        R                  " SR                  XU 5      5      eg! [         a    [        R                  " SU UU5         NLf = f)zConfirms 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.
zFHash mismatch for %s. Source hash (%s): %s, Destination hash (%s): %s.asciizMHash mismatch for %s and could not decode hashes. Source: %s, Destination: %sz@Source hash {} does not match destination hash {} for object {}.N)
r&   r   debugbinasciihexlifyr   	Exceptionr   HashMismatchErrorformat)object_pathsource_hashdestination_hashsource_hash_bytesdestination_hash_bytess        r   validate_object_hashes_matchrU      s     $6{C;<LM	ii




,
-
4
4W
=



1
2
9
9'
B" 
"
"	 &LN N+ %  	ii


s   A7B% %#C
Cc                T    U R                  5        H  nUR                  U5        M     g)z?Updates every hash object with new data in a dict of digesters.N)valuesr;   )	digestersr<   r)   s      r   update_digestersrY      s#    %%'kt (r   c                D    0 nU  H  nX   R                  5       X'   M     U$ )zBReturns copy of provided digesters since deepcopying doesn't work.)copy)rX   resultr.   s      r   copy_digestersr]      s*    &!n&6;;=F "	-r   c                   U  H~  nU[         R                  L a  [        R                  " 5       X'   M/  U[         R                  L a  [
        R                  " 5       X'   M[  [        R                  " SR                  U5      5      e   g)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   ErrorrO   )rX   r.   s     r   reset_digestersr`      sg    !n***")//"3i	=//	/"2"="="?iLL
9
@
@
P  "r   )r.   r   )NN)r6   rD   r)   zfast_crc32c_util.DeferredCrc32creturnz
int | None)r6   rD   r<   bytesr.   r   )r   
__future__r   r   rK   enum"googlecloudsdk.command_lib.storager   r   googlecloudsdk.corer   googlecloudsdk.core.updaterr   googlecloudsdk.core.utilr   r	   Enumr   r!   r&   r*   r/   r9   r=   rG   rU   rY   r]   r`   r   r   r   <module>rj      s    . "    5 ? # 2 * ,DII ?
&1
 		
0
  MQ
,980f"NJ
r   