
"""simple docstring"""

import argparse
import struct
import unittest






class 	_lowercase       :




	def __init__(			self		,			UpperCAmelCase_ )		->							None:
			lowerCamelCase					:      Optional[int]          =   data

			# Initialize hash values
			lowerCamelCase					:      str          =   [
			    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					:      str          =   [
			    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					:      Dict          =   self.preprocessing(self.data )
			self.final_hash()




	@staticmethod
	def       _UpperCamelCase   (			UpperCAmelCase_ )		->							bytes:
			lowerCamelCase					:      Union[str, Any]          =   b'\x80' + (b'\x00' * (63 - (len(UpperCAmelCase_ ) + 8) % 64))
			lowerCamelCase					:      Optional[int]          =   struct.pack('>Q'		,			(len(UpperCAmelCase_ ) * 8) )
			return data + padding + big_endian_integer




	def       _UpperCamelCase   (			self )		->							None:
			# Convert into blocks of 64 bytes
			lowerCamelCase					:      Union[str, Any]          =   [
			    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					:      Any          =   list(struct.unpack('>16L'		,			UpperCAmelCase_ ) )
					# add 48 0-ed integers
					words += [0] * 48

					lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase					:      Optional[Any]          =   self.hashes

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

									lowerCamelCase					:      int          =   (
									    words[index - 16] + sa + words[index - 7] + sa
									) % 0X1_00_00_00_00

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

							lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase     ,   lowerCamelCase					:      int          =   (
							    g,
							    f,
							    e,
							    ((d + tempa) % 0X1_00_00_00_00),
							    c,
							    b,
							    a,
							    ((tempa + tempa) % 0X1_00_00_00_00),
							)

					lowerCamelCase					:      Union[str, Any]          =   [a, b, c, d, e, f, g, h]

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

			lowerCamelCase					:      Tuple          =   ''.join([hex(UpperCAmelCase_ )[2:].zfill(8 ) for value in self.hashes] )




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






class 	_lowercase       (    unittest.TestCase		):




	def       _UpperCamelCase   (			self )		->							None:
			import hashlib

			lowerCamelCase					:      List[Any]          =   bytes('Test String'		,			'utf-8' )
			self.assertEqual(SHAaaa(UpperCAmelCase_ ).hash		,			hashlib.shaaaa(UpperCAmelCase_ ).hexdigest() )


def 		UpperCAmelCase (		):





		'''simple docstring'''


		import doctest

		doctest.testmod()

		lowerCamelCase					:      Any          =   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					:      Optional[int]          =   parser.parse_args()

		lowerCamelCase					:      Tuple          =   args.input_string

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

		print(SHAaaa(a_      ).hash      )


if __name__ == "__main__":
					main()








"""simple docstring"""

def 		UpperCAmelCase (		a_ = 10      ):





		'''simple docstring'''


		if not isinstance(a_,						a_      ) or n < 0:
				raise ValueError('Invalid input'      )
		lowerCamelCase					:      Union[str, Any]          =   10**n
		lowerCamelCase					:      int          =   2_8433 * (pow(2,						783_0457,						a_      )) + 1
		return str(number % modulus      )


if __name__ == "__main__":
					from doctest import testmod

					testmod()
					print(F"""{solution(1_0) = }""")






