


'''simple docstring'''



import argparse
import struct
import unittest





class    UpperCAmelCase_  :





    """simple docstring"""






    def __init__(							self			,     SCREAMING_SNAKE_CASE_	)				->     None:
         __lowerCamelCase   :	Any								=		data

         # Initialize hash values
         __lowerCamelCase   :	Union[str, Any]								=		[
             0X6a_09_e6_67,
             0Xbb_67_ae_85,
             0X3c_6e_f3_72,
             0Xa5_4f_f5_3a,
             0X51_0e_52_7f,
             0X9b_05_68_8c,
             0X1f_83_d9_ab,
             0X5b_e0_cd_19,
         ]

         # Initialize round constants
         __lowerCamelCase   :	Union[str, Any]								=		[
             0X42_8a_2f_98,
             0X71_37_44_91,
             0Xb5_c0_fb_cf,
             0Xe9_b5_db_a5,
             0X39_56_c2_5b,
             0X59_f1_11_f1,
             0X92_3f_82_a4,
             0Xab_1c_5e_d5,
             0Xd8_07_aa_98,
             0X12_83_5b_01,
             0X24_31_85_be,
             0X55_0c_7d_c3,
             0X72_be_5d_74,
             0X80_de_b1_fe,
             0X9b_dc_06_a7,
             0Xc1_9b_f1_74,
             0Xe4_9b_69_c1,
             0Xef_be_47_86,
             0X0f_c1_9d_c6,
             0X24_0c_a1_cc,
             0X2d_e9_2c_6f,
             0X4a_74_84_aa,
             0X5c_b0_a9_dc,
             0X76_f9_88_da,
             0X98_3e_51_52,
             0Xa8_31_c6_6d,
             0Xb0_03_27_c8,
             0Xbf_59_7f_c7,
             0Xc6_e0_0b_f3,
             0Xd5_a7_91_47,
             0X06_ca_63_51,
             0X14_29_29_67,
             0X27_b7_0a_85,
             0X2e_1b_21_38,
             0X4d_2c_6d_fc,
             0X53_38_0d_13,
             0X65_0a_73_54,
             0X76_6a_0a_bb,
             0X81_c2_c9_2e,
             0X92_72_2c_85,
             0Xa2_bf_e8_a1,
             0Xa8_1a_66_4b,
             0Xc2_4b_8b_70,
             0Xc7_6c_51_a3,
             0Xd1_92_e8_19,
             0Xd6_99_06_24,
             0Xf4_0e_35_85,
             0X10_6a_a0_70,
             0X19_a4_c1_16,
             0X1e_37_6c_08,
             0X27_48_77_4c,
             0X34_b0_bc_b5,
             0X39_1c_0c_b3,
             0X4e_d8_aa_4a,
             0X5b_9c_ca_4f,
             0X68_2e_6f_f3,
             0X74_8f_82_ee,
             0X78_a5_63_6f,
             0X84_c8_78_14,
             0X8c_c7_02_08,
             0X90_be_ff_fa,
             0Xa4_50_6c_eb,
             0Xbe_f9_a3_f7,
             0Xc6_71_78_f2,
         ]

         __lowerCamelCase   :	Any								=		self.preprocessing(self.data	)
         self.final_hash()







    @staticmethod
    def       lowercase_				(							SCREAMING_SNAKE_CASE_	)				->     bytes:
         __lowerCamelCase   :	Union[str, Any]								=		B'\x80' + (B'\x00' * (63 - (len(SCREAMING_SNAKE_CASE_	) + 8) % 64))
         __lowerCamelCase   :	List[Any]								=		struct.pack('>Q'			,     (len(SCREAMING_SNAKE_CASE_	) * 8)	)
         return data + padding + big_endian_integer







    def       lowercase_				(							self	)				->     None:
         # Convert into blocks of 64 bytes
         __lowerCamelCase   :	List[str]								=		[
             self.preprocessed_data[x : x + 64]
             for x in range(0			,     len(self.preprocessed_data	)			,     64	)
         ]

         for block in self.blocks:
              # Convert the given block into a list of 4 byte integers
              __lowerCamelCase   :	Optional[int]								=		list(struct.unpack('>16L'			,     SCREAMING_SNAKE_CASE_	)	)
              # add 48 0-ed integers
              words += [0] * 48

              __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase   :	List[Any]								=		self.hashes

              for index in range(0			,     64	):
                   if index > 15:
                        # modify the zero-ed indexes at the end of the array
                        __lowerCamelCase   :	Tuple								=		(
                            self.ror(words[index - 15]			,     7	)
                            ^ self.ror(words[index - 15]			,     18	)
                            ^ (words[index - 15] >> 3)
                        )
                        __lowerCamelCase   :	Optional[int]								=		(
                            self.ror(words[index - 2]			,     17	)
                            ^ self.ror(words[index - 2]			,     19	)
                            ^ (words[index - 2] >> 10)
                        )

                        __lowerCamelCase   :	Union[str, Any]								=		(
                            words[index - 16] + sa + words[index - 7] + sa
                        ) % 0X1_00_00_00_00

                   # Compression
                   __lowerCamelCase   :	Optional[Any]								=		self.ror(SCREAMING_SNAKE_CASE_			,     6	) ^ self.ror(SCREAMING_SNAKE_CASE_			,     11	) ^ self.ror(SCREAMING_SNAKE_CASE_			,     25	)
                   __lowerCamelCase   :	Any								=		(e & f) ^ ((~e & 0Xff_ff_ff_ff) & g)
                   __lowerCamelCase   :	Any								=		(
                       h + sa + ch + self.round_constants[index] + words[index]
                   ) % 0X1_00_00_00_00
                   __lowerCamelCase   :	Optional[Any]								=		self.ror(SCREAMING_SNAKE_CASE_			,     2	) ^ self.ror(SCREAMING_SNAKE_CASE_			,     13	) ^ self.ror(SCREAMING_SNAKE_CASE_			,     22	)
                   __lowerCamelCase   :	List[str]								=		(a & b) ^ (a & c) ^ (b & c)
                   __lowerCamelCase   :	List[Any]								=		(sa + maj) % 0X1_00_00_00_00

                   __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase				,       __lowerCamelCase   :	List[str]								=		(
                       g,
                       f,
                       e,
                       ((d + tempa) % 0X1_00_00_00_00),
                       c,
                       b,
                       a,
                       ((tempa + tempa) % 0X1_00_00_00_00),
                   )

              __lowerCamelCase   :	Tuple								=		[a, b, c, d, e, f, g, h]

              # Modify final values
              __lowerCamelCase   :	Any								=		[
                  ((element + mutated_hash_values[index]) % 0X1_00_00_00_00)
                  for index, element in enumerate(self.hashes	)
              ]

         __lowerCamelCase   :	Any								=		''.join([hex(SCREAMING_SNAKE_CASE_	)[2:].zfill(8	) for value in self.hashes]	)







    def       lowercase_				(							self			,     SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_	)				->     int:
         return 0Xff_ff_ff_ff & (value << (32 - rotations)) | (value >> rotations)







class    UpperCAmelCase_  (unittest.TestCase  ):





    """simple docstring"""






    def       lowercase_				(							self	)				->     None:
         import hashlib

         __lowerCamelCase   :	Any								=		bytes('Test String'			,     'utf-8'	)
         self.assertEqual(SHAaaa(SCREAMING_SNAKE_CASE_	).hash			,     hashlib.shaaaa(SCREAMING_SNAKE_CASE_	).hexdigest()	)







def 			UpperCAmelCase__					(	)     ->		None:
     import doctest

     doctest.testmod()

     __lowerCamelCase   :	List[str]								=		argparse.ArgumentParser()
     parser.add_argument(
         '-s'      ,    '--string'      ,    dest='input_string'      ,    default='Hello World!! Welcome to Cryptography'      ,    help='Hash the string'      ,    )
     parser.add_argument(
         '-f'      ,    '--file'      ,    dest='input_file'      ,    help='Hash contents of a file'							)

     __lowerCamelCase   :	Any								=		parser.parse_args()

     __lowerCamelCase   :	Optional[int]								=		args.input_string

     # hash input should be a bytestring
     if args.input_file:
          with open(args.input_file      ,    'rb'							) as f:
               __lowerCamelCase   :	Optional[int]								=		f.read()
     else:
          __lowerCamelCase   :	int								=		bytes(UpperCAmelCase_      ,    'utf-8'							)

     print(SHAaaa(UpperCAmelCase_							).hash							)


if __name__ == "__main__":
      main()










'''simple docstring'''



from importlib import import_module

from .logging import get_logger


A__		:					str												=  get_logger(__name__)





class    UpperCAmelCase_  :





    """simple docstring"""






    def __init__(							self			,     SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_=None	)				->     List[Any]:
         __lowerCamelCase   :	List[str]								=		attrs or []
         if module is not None:
              for key in module.__dict__:
                   if key in attrs or not key.startswith('__'	):
                        setattr(self			,     SCREAMING_SNAKE_CASE_			,     getattr(SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_	)	)
         __lowerCamelCase   :	Optional[int]								=		module._original_module if isinstance(SCREAMING_SNAKE_CASE_			,     _PatchedModuleObj	) else module







class    UpperCAmelCase_  :





    """simple docstring"""






    lowerCamelCase  :					Tuple							     =			[]







    def __init__(							self			,     SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_=None	)				->     Union[str, Any]:
         __lowerCamelCase   :	Optional[int]								=		obj
         __lowerCamelCase   :	List[Any]								=		target
         __lowerCamelCase   :	Union[str, Any]								=		new
         __lowerCamelCase   :	Union[str, Any]								=		target.split('.'	)[0]
         __lowerCamelCase   :	Dict								=		{}
         __lowerCamelCase   :	Dict								=		attrs or []







    def __enter__(							self	)				->     Optional[int]:
         *__lowerCamelCase				,       __lowerCamelCase   :	int								=		self.target.split('.'	)

         # Patch modules:
         # it's used to patch attributes of submodules like "os.path.join";
         # in this case we need to patch "os" and "os.path"

         for i in range(len(SCREAMING_SNAKE_CASE_	)	):
              try:
                   __lowerCamelCase   :	Optional[int]								=		import_module('.'.join(submodules[: i + 1]	)	)
              except ModuleNotFoundError:
                   continue
              # We iterate over all the globals in self.obj in case we find "os" or "os.path"
              for attr in self.obj.__dir__():
                   __lowerCamelCase   :	List[Any]								=		getattr(self.obj			,     SCREAMING_SNAKE_CASE_	)
                   # We don't check for the name of the global, but rather if its value *is* "os" or "os.path".
                   # This allows to patch renamed modules like "from os import path as ospath".
                   if obj_attr is submodule or (
                       (isinstance(SCREAMING_SNAKE_CASE_			,     _PatchedModuleObj	) and obj_attr._original_module is submodule)
                   ):
                        __lowerCamelCase   :	Optional[Any]								=		obj_attr
                        # patch at top level
                        setattr(self.obj			,     SCREAMING_SNAKE_CASE_			,     _PatchedModuleObj(SCREAMING_SNAKE_CASE_			,     attrs=self.attrs	)	)
                        __lowerCamelCase   :	str								=		getattr(self.obj			,     SCREAMING_SNAKE_CASE_	)
                        # construct lower levels patches
                        for key in submodules[i + 1 :]:
                             setattr(SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_			,     _PatchedModuleObj(getattr(SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_	)			,     attrs=self.attrs	)	)
                             __lowerCamelCase   :	List[Any]								=		getattr(SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_	)
                        # finally set the target attribute
                        setattr(SCREAMING_SNAKE_CASE_			,     SCREAMING_SNAKE_CASE_			,     self.new	)

        # Patch attribute itself:
        # it's used for builtins like "open",
        # and also to patch "os.path.join" we may also need to patch "join"
        # itself if it was imported as "from os.path import join".

         if submodules:  # if it's an attribute of a submodule like "os.path.join"
              try:
                   __lowerCamelCase   :	Union[str, Any]								=		getattr(import_module('.'.join(SCREAMING_SNAKE_CASE_	)	)			,     SCREAMING_SNAKE_CASE_	)
              except (AttributeError, ModuleNotFoundError):
                   return
              # We iterate over all the globals in self.obj in case we find "os.path.join"
              for attr in self.obj.__dir__():
                   # We don't check for the name of the global, but rather if its value *is* "os.path.join".
                   # This allows to patch renamed attributes like "from os.path import join as pjoin".
                   if getattr(self.obj			,     SCREAMING_SNAKE_CASE_	) is attr_value:
                        __lowerCamelCase   :	Optional[int]								=		getattr(self.obj			,     SCREAMING_SNAKE_CASE_	)
                        setattr(self.obj			,     SCREAMING_SNAKE_CASE_			,     self.new	)
         elif target_attr in globals()["__builtins__"]:  # if it'a s builtin like "open"
              __lowerCamelCase   :	List[Any]								=		globals()['__builtins__'][target_attr]
              setattr(self.obj			,     SCREAMING_SNAKE_CASE_			,     self.new	)
         else:
              raise RuntimeError(f'Tried to patch attribute {target_attr} instead of a submodule.'	)







    def __exit__(							self			,     *SCREAMING_SNAKE_CASE_	)				->     Optional[Any]:
         for attr in list(self.original	):
              setattr(self.obj			,     SCREAMING_SNAKE_CASE_			,     self.original.pop(SCREAMING_SNAKE_CASE_	)	)







    def       lowercase_				(							self	)				->     Optional[int]:
         self.__enter__()
         self._active_patches.append(self	)







    def       lowercase_				(							self	)				->     str:
         try:
              self._active_patches.remove(self	)
         except ValueError:
              # If the patch hasn't been started this will fail
              return None

         return self.__exit__()






