





'''simple docstring'''






import argparse
import struct
import unittest
class 				lowerCamelCase  :



	def __init__(   self		,      a_	):
			lowerCAmelCase     :    Dict						=   data

			# Initialize hash values
			lowerCAmelCase     :    Any						=   [
			    0x6a09e667,
			    0xbb67ae85,
			    0x3c6ef372,
			    0xa54ff53a,
			    0x510e527f,
			    0x9b05688c,
			    0x1f83d9ab,
			    0x5be0cd19,
			]

			# Initialize round constants
			lowerCAmelCase     :    Optional[int]						=   [
			    0x428a2f98,
			    0x71374491,
			    0xb5c0fbcf,
			    0xe9b5dba5,
			    0x3956c25b,
			    0x59f111f1,
			    0x923f82a4,
			    0xab1c5ed5,
			    0xd807aa98,
			    0x12835b01,
			    0x243185be,
			    0x550c7dc3,
			    0x72be5d74,
			    0x80deb1fe,
			    0x9bdc06a7,
			    0xc19bf174,
			    0xe49b69c1,
			    0xefbe4786,
			    0x0fc19dc6,
			    0x240ca1cc,
			    0x2de92c6f,
			    0x4a7484aa,
			    0x5cb0a9dc,
			    0x76f988da,
			    0x983e5152,
			    0xa831c66d,
			    0xb00327c8,
			    0xbf597fc7,
			    0xc6e00bf3,
			    0xd5a79147,
			    0x06ca6351,
			    0x14292967,
			    0x27b70a85,
			    0x2e1b2138,
			    0x4d2c6dfc,
			    0x53380d13,
			    0x650a7354,
			    0x766a0abb,
			    0x81c2c92e,
			    0x92722c85,
			    0xa2bfe8a1,
			    0xa81a664b,
			    0xc24b8b70,
			    0xc76c51a3,
			    0xd192e819,
			    0xd6990624,
			    0xf40e3585,
			    0x106aa070,
			    0x19a4c116,
			    0x1e376c08,
			    0x2748774c,
			    0x34b0bcb5,
			    0x391c0cb3,
			    0x4ed8aa4a,
			    0x5b9cca4f,
			    0x682e6ff3,
			    0x748f82ee,
			    0x78a5636f,
			    0x84c87814,
			    0x8cc70208,
			    0x90befffa,
			    0xa4506ceb,
			    0xbef9a3f7,
			    0xc67178f2,
			]

			lowerCAmelCase     :    str						=   self.preprocessing(self.data	)
			self.final_hash()



	@staticmethod
	def   _lowerCamelCase    (   a_	):
			lowerCAmelCase     :    Any						=   B"\x80" + (B"\x00" * (63 - (len(a_	) + 8) % 64))
			lowerCAmelCase     :    str						=   struct.pack(">Q"		,      (len(a_	) * 8)	)
			return data + padding + big_endian_integer



	def   _lowerCamelCase    (   self	):
			# 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     :    List[str]						=   list(struct.unpack(">16L"		,      a_	)	)
					# add 48 0-ed integers
					words += [0] * 48

					lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase     :    Tuple						=   self.hashes

					for index in range(0		,      64	):
							if index > 15:
									# modify the zero-ed indexes at the end of the array
									lowerCAmelCase     :    Dict						=   (
									    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     :    str						=   (
									    words[index - 16] + sa + words[index - 7] + sa
									) % 0x100000000

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

							lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase	,		lowerCAmelCase     :    List[Any]						=   (
							    g,
							    f,
							    e,
							    ((d + tempa) % 0x100000000),
							    c,
							    b,
							    a,
							    ((tempa + tempa) % 0x100000000),
							)

					lowerCAmelCase     :    str						=   [a, b, c, d, e, f, g, h]

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

			lowerCAmelCase     :    int						=   "".join([hex(a_	)[2:].zfill(8	) for value in self.hashes]	)





	def   _lowerCamelCase    (   self		,      a_		,      a_	):
			return 0xffffffff & (value << (32 - rotations)) | (value >> rotations)






class 				lowerCamelCase  (      unittest.TestCase       ):



	def   _lowerCamelCase    (   self	):
			import hashlib

			lowerCAmelCase     :    Any						=   bytes("Test String"		,      "utf-8"	)
			self.assertEqual(SHAaaa(a_	).hash		,      hashlib.shaaaa(a_	).hexdigest()	)






def      __A						(							):
		import doctest

		doctest.testmod()

		lowerCAmelCase     :    Optional[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     :    Dict						=   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     :    int						=   f.read()
		else:
				lowerCAmelCase     :    Union[str, Any]						=   bytes(a_      ,"utf-8"	)

		print(SHAaaa(a_	).hash	)


if __name__ == "__main__":
					main()










'''simple docstring'''






def      __A						(							a_						:  int	):
		assert (
		    isinstance(a_      ,a_	) and number_of_steps > 0
		), f'''number_of_steps needs to be positive integer, your input {number_of_steps}'''
		if number_of_steps == 1:
				return 1
		lowerCAmelCase	,		lowerCAmelCase     :    int						=   1, 1
		for _ in range(number_of_steps - 1	):
				lowerCAmelCase	,		lowerCAmelCase     :    Union[str, Any]						=   current + previous, current
		return current


if __name__ == "__main__":
					import doctest

					doctest.testmod()



