
                        "   S r SSKJr  SSKJr  SSKJr  SSKJ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\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.    )absolute_import)annotations)division)unicode_literalsN)errors)fast_crc32c_util)
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,   2   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_objectr1   7   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stopr3   r4   s         r   _get_hash_for_deferred_crc32cr;   @   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)r1   r5   r   r6   r;   update)r8   datar0   r9   r:   r+   s         r    get_hash_from_data_chunk_or_filer?   N   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   )r1   r5   r   r6   r;   r
   BinaryFileReaderseektellr	   WRITE_BUFFER_SIZEreadstrr%   r=   )r8   r0   r9   r:   r+   streambytes_to_readr>   s           r   get_hash_from_filerI   j   s   $  /+-<<==(EHHd#vkk%
	&++-4' 
)E)EEL"44{{},[['d	D#		{{7#%  $. 
/ $#. 
s   CD..
D=c                Z    X:w  a&  [         R                  " SR                  XU 5      5      eg)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.
z@Source hash {} does not match destination hash {} for object {}.N)r   HashMismatchErrorformat)object_pathsource_hashdestination_hashs      r   validate_object_hashes_matchrP      s5     $

"
"	 &LN N %r   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_digestersrT      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)rS   resultr0   s      r   copy_digestersrX      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   ErrorrL   )rS   r0   s     r   reset_digestersr[      sg    !n***")//"3i	=//	/"2"="="?iLL
9
@
@
P  "r   )r0   r   )NN)r8   rF   r+   zfast_crc32c_util.DeferredCrc32creturnz
int | None)r8   rF   r>   bytesr0   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,   r1   r;   r?   rI   rP   rT   rX   r[   r   r   r   <module>rd      s    . & "  '   5 ? 2 * ,DII ?
&1
 		
0
  MQ
,980fN"
r   