

import argparse
import struct
import unittest





class       snake_case_  :







			'''simple docstring'''

			def __init__(	self					:							Union[str, Any]				,  _UpperCamelCase					:							bytes				) ->None:
									snake_case_  =      data

									# Initialize hash values
									snake_case_  =      [
									    0x6_a_0_9_e_6_6_7,
									    0xb_b_6_7_a_e_8_5,
									    0x3_c_6_e_f_3_7_2,
									    0xa_5_4_f_f_5_3_a,
									    0x5_1_0_e_5_2_7_f,
									    0x9_b_0_5_6_8_8_c,
									    0x1_f_8_3_d_9_a_b,
									    0x5_b_e_0_c_d_1_9,
									]

									# Initialize round constants
									snake_case_  =      [
									    0x4_2_8_a_2_f_9_8,
									    0x7_1_3_7_4_4_9_1,
									    0xb_5_c_0_f_b_c_f,
									    0xe_9_b_5_d_b_a_5,
									    0x3_9_5_6_c_2_5_b,
									    0x5_9_f_1_1_1_f_1,
									    0x9_2_3_f_8_2_a_4,
									    0xa_b_1_c_5_e_d_5,
									    0xd_8_0_7_a_a_9_8,
									    0x1_2_8_3_5_b_0_1,
									    0x2_4_3_1_8_5_b_e,
									    0x5_5_0_c_7_d_c_3,
									    0x7_2_b_e_5_d_7_4,
									    0x8_0_d_e_b_1_f_e,
									    0x9_b_d_c_0_6_a_7,
									    0xc_1_9_b_f_1_7_4,
									    0xe_4_9_b_6_9_c_1,
									    0xe_f_b_e_4_7_8_6,
									    0x0_f_c_1_9_d_c_6,
									    0x2_4_0_c_a_1_c_c,
									    0x2_d_e_9_2_c_6_f,
									    0x4_a_7_4_8_4_a_a,
									    0x5_c_b_0_a_9_d_c,
									    0x7_6_f_9_8_8_d_a,
									    0x9_8_3_e_5_1_5_2,
									    0xa_8_3_1_c_6_6_d,
									    0xb_0_0_3_2_7_c_8,
									    0xb_f_5_9_7_f_c_7,
									    0xc_6_e_0_0_b_f_3,
									    0xd_5_a_7_9_1_4_7,
									    0x0_6_c_a_6_3_5_1,
									    0x1_4_2_9_2_9_6_7,
									    0x2_7_b_7_0_a_8_5,
									    0x2_e_1_b_2_1_3_8,
									    0x4_d_2_c_6_d_f_c,
									    0x5_3_3_8_0_d_1_3,
									    0x6_5_0_a_7_3_5_4,
									    0x7_6_6_a_0_a_b_b,
									    0x8_1_c_2_c_9_2_e,
									    0x9_2_7_2_2_c_8_5,
									    0xa_2_b_f_e_8_a_1,
									    0xa_8_1_a_6_6_4_b,
									    0xc_2_4_b_8_b_7_0,
									    0xc_7_6_c_5_1_a_3,
									    0xd_1_9_2_e_8_1_9,
									    0xd_6_9_9_0_6_2_4,
									    0xf_4_0_e_3_5_8_5,
									    0x1_0_6_a_a_0_7_0,
									    0x1_9_a_4_c_1_1_6,
									    0x1_e_3_7_6_c_0_8,
									    0x2_7_4_8_7_7_4_c,
									    0x3_4_b_0_b_c_b_5,
									    0x3_9_1_c_0_c_b_3,
									    0x4_e_d_8_a_a_4_a,
									    0x5_b_9_c_c_a_4_f,
									    0x6_8_2_e_6_f_f_3,
									    0x7_4_8_f_8_2_e_e,
									    0x7_8_a_5_6_3_6_f,
									    0x8_4_c_8_7_8_1_4,
									    0x8_c_c_7_0_2_0_8,
									    0x9_0_b_e_f_f_f_a,
									    0xa_4_5_0_6_c_e_b,
									    0xb_e_f_9_a_3_f_7,
									    0xc_6_7_1_7_8_f_2,
									]

									snake_case_  =      self.preprocessing(self.data				)
									self.final_hash()







			@staticmethod
			def 							snake_case__(	_UpperCamelCase					:							bytes				) ->bytes:
									snake_case_  =      B'''\x80''' + (B'''\x00''' * (6_3 - (len(_UpperCamelCase				) + 8) % 6_4))
									snake_case_  =      struct.pack('''>Q'''				,  (len(_UpperCamelCase				) * 8)				)
									return data + padding + big_endian_integer







			def 							snake_case__(	self					:							Optional[Any]				) ->None:
									# Convert into blocks of 64 bytes
									snake_case_  =      [
									    self.preprocessed_data[x : x + 6_4]
									    for x in range(0				,  len(self.preprocessed_data				)				,  6_4				)
									]

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

															snake_case_,       snake_case_,       snake_case_,       snake_case_,       snake_case_,       snake_case_,       snake_case_,       snake_case_  =      self.hashes

															for index in range(0				,  6_4				):
																					if index > 1_5:
																											# modify the zero-ed indexes at the end of the array
																											snake_case_  =      (
																											    self.ror(words[index - 1_5]				,  7				)
																											    ^ self.ror(words[index - 1_5]				,  1_8				)
																											    ^ (words[index - 1_5] >> 3)
																											)
																											snake_case_  =      (
																											    self.ror(words[index - 2]				,  1_7				)
																											    ^ self.ror(words[index - 2]				,  1_9				)
																											    ^ (words[index - 2] >> 1_0)
																											)

																											snake_case_  =      (
																											    words[index - 1_6] + sa + words[index - 7] + sa
																											) % 0x1_0_0_0_0_0_0_0_0

																					# Compression
																					snake_case_  =      self.ror(_UpperCamelCase				,  6				) ^ self.ror(_UpperCamelCase				,  1_1				) ^ self.ror(_UpperCamelCase				,  2_5				)
																					snake_case_  =      (e & f) ^ ((~e & 0xf_f_f_f_f_f_f_f) & g)
																					snake_case_  =      (
																					    h + sa + ch + self.round_constants[index] + words[index]
																					) % 0x1_0_0_0_0_0_0_0_0
																					snake_case_  =      self.ror(_UpperCamelCase				,  2				) ^ self.ror(_UpperCamelCase				,  1_3				) ^ self.ror(_UpperCamelCase				,  2_2				)
																					snake_case_  =      (a & b) ^ (a & c) ^ (b & c)
																					snake_case_  =      (sa + maj) % 0x1_0_0_0_0_0_0_0_0

																					snake_case_,       snake_case_,       snake_case_,       snake_case_,       snake_case_,       snake_case_,       snake_case_,       snake_case_  =      (
																					    g,
																					    f,
																					    e,
																					    ((d + tempa) % 0x1_0_0_0_0_0_0_0_0),
																					    c,
																					    b,
																					    a,
																					    ((tempa + tempa) % 0x1_0_0_0_0_0_0_0_0),
																					)

															snake_case_  =      [a, b, c, d, e, f, g, h]

															# Modify final values
															snake_case_  =      [
															    ((element + mutated_hash_values[index]) % 0x1_0_0_0_0_0_0_0_0)
															    for index, element in enumerate(self.hashes				)
															]

									snake_case_  =      ''''''.join([hex(_UpperCamelCase				)[2:].zfill(8				) for value in self.hashes]				)







			def 							snake_case__(	self					:							Union[str, Any]				,  _UpperCamelCase					:							int				,  _UpperCamelCase					:							int				) ->int:
									return 0xf_f_f_f_f_f_f_f & (value << (3_2 - rotations)) | (value >> rotations)






class       snake_case_  (						unittest.TestCase   ):







			'''simple docstring'''

			def 							snake_case__(	self					:							Any				) ->None:
									import hashlib

									snake_case_  =      bytes('''Test String'''				,  '''utf-8'''				)
									self.assertEqual(SHAaaa(_UpperCamelCase				).hash				,  hashlib.shaaaa(_UpperCamelCase				).hexdigest()				)






def     __SCREAMING_SNAKE_CASE   ():
						import doctest

						doctest.testmod()

						snake_case_  =      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'''			)

						snake_case_  =      parser.parse_args()

						snake_case_  =      args.input_string

						# hash input should be a bytestring
						if args.input_file:
												with open(args.input_file    ,						'''rb'''			) as f:
																		snake_case_  =      f.read()
						else:
												snake_case_  =      bytes(SCREAMING_SNAKE_CASE__    ,						'''utf-8'''			)

						print(SHAaaa(SCREAMING_SNAKE_CASE__			).hash			)


if __name__ == "__main__":
					main()







# Lint as: python3
import sys
from collections.abc import Mapping
from typing import TYPE_CHECKING

import numpy as np
import pyarrow as pa

from .. import config
from ..utils.py_utils import map_nested
from .formatting import TensorFormatter


if TYPE_CHECKING:
     import torch




class       snake_case__ (				TensorFormatter[Mapping, "torch.Tensor", Mapping]):

       '''simple docstring'''



       def __init__(				self      ,    a__=None      ,    **a__     )			->   Tuple:






            '''simple docstring'''





            super().__init__(features=a__     )
            __snake_case      :int 							=    torch_tensor_kwargs
            import torch  # noqa import torch at initialization



       def        __lowercase    (				self      ,    a__     )			->   List[str]:






            '''simple docstring'''





            import torch

            if isinstance(a__      ,    a__     ) and column:
                 if all(
                     isinstance(a__      ,    torch.Tensor     ) and x.shape == column[0].shape and x.dtype == column[0].dtype
                     for x in column     ):
                      return torch.stack(a__     )
            return column



       def        __lowercase    (				self      ,    a__     )			->   Union[str, Any]:






            '''simple docstring'''





            import torch

            if isinstance(a__      ,    (str, bytes, type(a__     ))     ):
                 return value
            elif isinstance(a__      ,    (np.character, np.ndarray)     ) and np.issubdtype(value.dtype      ,    np.character     ):
                 return value.tolist()

            __snake_case      :Optional[int] 							=    {}

            if isinstance(a__      ,    (np.number, np.ndarray)     ) and np.issubdtype(value.dtype      ,    np.integer     ):
                 __snake_case      :List[Any] 							=    {"""dtype""": torch.intaa}
            elif isinstance(a__      ,    (np.number, np.ndarray)     ) and np.issubdtype(value.dtype      ,    np.floating     ):
                 __snake_case      :Tuple 							=    {"""dtype""": torch.floataa}
            elif config.PIL_AVAILABLE and "PIL" in sys.modules:
                 import PIL.Image

                 if isinstance(a__      ,    PIL.Image.Image     ):
                      __snake_case      :Union[str, Any] 							=    np.asarray(a__     )
            return torch.tensor(a__      ,    **{**default_dtype, **self.torch_tensor_kwargs}     )



       def        __lowercase    (				self      ,    a__     )			->   str:






            '''simple docstring'''





            import torch

            # support for torch, tf, jax etc.
            if hasattr(a__      ,    """__array__"""     ) and not isinstance(a__      ,    torch.Tensor     ):
                 __snake_case      :Optional[Any] 							=    data_struct.__array__()
            # support for nested types like struct of list of struct
            if isinstance(a__      ,    np.ndarray     ):
                 if data_struct.dtype == object:  # torch tensors cannot be instantied from an array of objects
                      return self._consolidate([self.recursive_tensorize(a__     ) for substruct in data_struct]     )
            elif isinstance(a__      ,    (list, tuple)     ):
                 return self._consolidate([self.recursive_tensorize(a__     ) for substruct in data_struct]     )
            return self._tensorize(a__     )



       def        __lowercase    (				self      ,    a__     )			->   Union[str, Any]:






            '''simple docstring'''





            return map_nested(self._recursive_tensorize      ,    a__      ,    map_list=a__     )



       def        __lowercase    (				self      ,    a__     )			->   Mapping:






            '''simple docstring'''





            __snake_case      :Tuple 							=    self.numpy_arrow_extractor().extract_row(a__     )
            __snake_case      :Any 							=    self.python_features_decoder.decode_row(a__     )
            return self.recursive_tensorize(a__     )



       def        __lowercase    (				self      ,    a__     )			->   "torch.Tensor":






            '''simple docstring'''





            __snake_case      :List[str] 							=    self.numpy_arrow_extractor().extract_column(a__     )
            __snake_case      :List[Any] 							=    self.python_features_decoder.decode_column(a__      ,    pa_table.column_names[0]     )
            __snake_case      :Optional[Any] 							=    self.recursive_tensorize(a__     )
            __snake_case      :Any 							=    self._consolidate(a__     )
            return column



       def        __lowercase    (				self      ,    a__     )			->   Mapping:






            '''simple docstring'''





            __snake_case      :Optional[int] 							=    self.numpy_arrow_extractor().extract_batch(a__     )
            __snake_case      :Tuple 							=    self.python_features_decoder.decode_batch(a__     )
            __snake_case      :Tuple 							=    self.recursive_tensorize(a__     )
            for column_name in batch:
                 __snake_case      :str 							=    self._consolidate(batch[column_name]     )
            return batch


