
    &                     *   d 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 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 ddlmZ dZdZdZdZd Zd Zd Zej<                   G d dej>                               Z y)zAImplementation of hash command for getting formatted file hashes.    )absolute_import)division)unicode_literalsN)base)encryption_util)errors)fast_crc32c_util)flags)	hash_util)storage_url)wildcard_iterator)resource_reference)crc32c)logdigest_formatcrc32c_hashmd5_hashurlc                     | yt        j                  t        j                  | j	                  d      j                  d                  j                  d      S )z@Converts base64 hash digest to hex-formatted hash digest string.Nz
"'zutf-8)binasciihexlifybase64	b64decodestripencodedecode)base64_strings    lib/surface/storage/hash.py_convert_base64_to_hexr   *   sO    			


g
&
-
-g
68
99?I    c                 V    t        | t        j                  t        j                  f      S N)
isinstancer   ObjectResourceFileObjectResource)resources    r   _is_object_or_file_resourcer'   3   s+    	H1@@1DDF 
G Gr    c              #   P  K   d}| D ]  }t        j                  |dd      }d}|D ]  }t        |      r	dx}}| t        |j                  t        j
                        s<|j                  j                         sWt        j                  |j                  j                  d      j                  d      }|D ]%  }t        |t        j                        sdx}}| '  |rt        j                  dj                  |              |st        j                  d      yw)	z8Wildcard matches and recurses into top-level of buckets.FT)error_on_missing_keyfetch_encrypted_object_hashes*)r)   zNo matches found for {}zNo URLS matched.N)r   get_wildcard_iteratorr'   r#   r   CloudUrl	is_bucketjoin
url_stringr   r$   r   warningformatr   InvalidUrlError)url_stringsany_url_matchedr0   wildcard_expanded_iteratorthis_url_matchedwildcard_expanded_resourcebucket_expanded_iteratorbucket_expanded_resources           r   _get_resource_iteratorr;   8   s$    /j!2!H!H"&*", &@"	$%?	@-11*((1=="++-&22<<>#4#J#J&2277<GG!&$(  )A$0+::=155O.**	 )A 'A 	kk+22:>?-  . 


 
 !3
44 
s   A D&#D&>AD&D&'?D&c                   0    e Zd ZdZdddZed        Zd Zy)Hashz*Calculates hashes on local or cloud files.ad  
      Calculates hashes on local or cloud files that can be used to compare with
      "gcloud storage ls -L" output. If a specific hash option is not provided,
      this command calculates all gcloud storage-supported hashes for the file.

      Note that gcloud storage automatically performs hash validation when
      uploading or downloading files, so this command is only needed if you want
      to write a script that separately checks the hash for some reason.

      If you calculate a CRC32C hash for the file without a precompiled
      google-crc32c installation, hashing will be very slow.
      a  

      To get the MD5 and CRC32C hash digest of a cloud object in Base64 format:

        $ {command} gs://bucket/object

      To get just the MD5 hash digest of a local object in hex format:

        $ {command} /dir/object.txt --skip-crc32c --hex
      )DESCRIPTIONEXAMPLESc                     | j                  ddd       | j                  ddd       | j                  d	
      }|j                  ddd       |j                  ddd       t        j                  | d	       t        j                  |        y )Nurls+z'Local or cloud URLs of objects to hash.)nargshelpz--hex
store_truezOOutput hash digests in hex format. By default, digests are displayed in base64.)actionrD   T)mutexz--skip-crc32cz@Skip CRC32C hash calculation. Useful if command is running slow.z
--skip-md5z=Skip MD5 hash calculation. Useful if command is running slow.)command_only_reads_data)add_argument	add_groupr
   add_encryption_flagsadd_additional_headers_flag)parserskip_flags_groups     r   Argsz	Hash.Argsu   s    
c I  K
   !
 ''d'3!!O " Q !!L " N 
vtD	%%f-r    c              #     K   t        j                  |       |j                  sPt        j                         rd}nt
        j                  rd}nd}t        j                  dj                  |             |j                  rd}t        }d }nd}d }t        j                  }t        |j                        D ]  }t         |i}t#        |t$        j&                        r|j(                  1|j*                  %t        j,                  d	j                  |             c|j.                  j0                  |t2        <   |j                  s ||j(                        |t4        <   |j6                  s ||j*                        |t8        <   n|j.                  j:                  |t2        <   |j                  sO |t        j<                  |j.                  j:                  t        j>                  j@                              |t4        <   |j6                  sO |t        j<                  |j.                  j:                  t        j>                  jB                              |t8        <   |  y w)
Nzgcloud-crc32c (Go binary)zgoogle-crc32c (Python binary)z(crcmod (slow pure Python implementation)zCRC32C implementation: {}hexc                 "    | j                         S r"   )	hexdigestxs    r   <lambda>zHash.Run.<locals>.<lambda>   s
    !++-r    r   c                     | S r"    rT   s    r   rV   zHash.Run.<locals>.<lambda>   s    ar    zNo hashes found for {})"r   initialize_key_storeskip_crc32cr	   should_use_gcloud_crc32cr   IS_FAST_GOOGLE_CRC32C_AVAILABLEr   infor2   rQ   r   r   get_base64_hash_digest_stringr;   rA   _DIGEST_FORMAT_KEYr#   r   r$   r   r   r1   r   versionless_url_string_URL_KEY_CRC32C_HASH_KEYskip_md5_MD5_HASH_KEYresource_nameget_hash_from_fileHashAlgorithmCRC32CMD5)selfargscrc32c_implementationhash_formatformat_cloud_digestformat_file_hash_objectr&   output_dicts           r   RunzHash.Run   s    ((.		2	2	4 ;11 ? J	hh*112GHIxxk2 7k' ) G G*4995
kk 
H0??	@'H,=,=,E
++.55h?
@
 ( 4 4 K KH*=""+$+&
'}}':8;L;L'M+m
$ ( 4 4 B BH*A**&&44))00++&
' }}'>**&&44))--(+m
$ = 6s   IIN)__name__
__module____qualname____doc__detailed_helpstaticmethodrO   rq   rX   r    r   r=   r=   V   s/    2
	
-6 . .*3r    r=   )!ru   
__future__r   r   r   r   r   googlecloudsdk.callioper   "googlecloudsdk.command_lib.storager   r   r	   r
   r   r   r   ,googlecloudsdk.command_lib.storage.resourcesr   googlecloudsdk.command_lib.utilr   googlecloudsdk.corer   r_   rb   rd   ra   r   r'   r;   UniverseCompatibleCommandr=   rX   r    r   <module>r      s    H &  '   ( > 5 ? 4 8 : @ K 2 #$   IG
5< g4<< g gr    