
import argparse
import hashlib  # hashlib is only used inside the Test class
import struct





class 			_lowerCAmelCase      :




				def __init__(      self       ,       _UpperCamelCase  )       ->   Any:
							lowerCAmelCase_      			=			data
							lowerCAmelCase_      			=			[0x6_7_4_5_2_3_0_1, 0xE_F_C_D_A_B_8_9, 0x9_8_B_A_D_C_F_E, 0x1_0_3_2_5_4_7_6, 0xC_3_D_2_E_1_F_0]




				@staticmethod
				def   __a		(      _UpperCamelCase       ,       _UpperCamelCase  )       ->   Dict:
							return ((n << b) | (n >> (32 - b))) & 0xF_F_F_F_F_F_F_F




				def   __a		(      self  )       ->   Any:
							lowerCAmelCase_      			=			B"\x80" + B"\x00" * (63 - (len(self.data  ) + 8) % 64)
							lowerCAmelCase_      			=			self.data + padding + struct.pack(">Q"       ,       8 * len(self.data  )  )
							return padded_data




				def   __a		(      self  )       ->   Union[str, Any]:
							return [
							    self.padded_data[i : i + 64] for i in range(0       ,       len(self.padded_data  )       ,       64  )
							]




				def   __a		(      self       ,       _UpperCamelCase  )       ->   List[str]:
							lowerCAmelCase_      			=			list(struct.unpack(">16L"       ,       _UpperCamelCase  )  ) + [0] * 64
							for i in range(16       ,       80  ):
										lowerCAmelCase_      			=			self.rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16])       ,       1  )
							return w




				def   __a		(      self  )       ->   Optional[int]:
							lowerCAmelCase_      			=			self.padding()
							lowerCAmelCase_      			=			self.split_blocks()
							for block in self.blocks:
										lowerCAmelCase_      			=			self.expand_block(_UpperCamelCase  )
										lowerCAmelCase_			,						lowerCAmelCase_			,						lowerCAmelCase_			,						lowerCAmelCase_			,						lowerCAmelCase_      			=			self.h
										for i in range(0       ,       80  ):
													if 0 <= i < 20:
																lowerCAmelCase_      			=			(b & c) | ((~b) & d)
																lowerCAmelCase_      			=			0x5_A_8_2_7_9_9_9
													elif 20 <= i < 40:
																lowerCAmelCase_      			=			b ^ c ^ d
																lowerCAmelCase_      			=			0x6_E_D_9_E_B_A_1
													elif 40 <= i < 60:
																lowerCAmelCase_      			=			(b & c) | (b & d) | (c & d)
																lowerCAmelCase_      			=			0x8_F_1_B_B_C_D_C
													elif 60 <= i < 80:
																lowerCAmelCase_      			=			b ^ c ^ d
																lowerCAmelCase_      			=			0xC_A_6_2_C_1_D_6
													lowerCAmelCase_			,						lowerCAmelCase_			,						lowerCAmelCase_			,						lowerCAmelCase_			,						lowerCAmelCase_      			=			(
													    self.rotate(_UpperCamelCase       ,       5  ) + f + e + k + expanded_block[i] & 0xF_F_F_F_F_F_F_F,
													    a,
													    self.rotate(_UpperCamelCase       ,       30  ),
													    c,
													    d,
													)
										lowerCAmelCase_      			=			(
										    self.h[0] + a & 0xF_F_F_F_F_F_F_F,
										    self.h[1] + b & 0xF_F_F_F_F_F_F_F,
										    self.h[2] + c & 0xF_F_F_F_F_F_F_F,
										    self.h[3] + d & 0xF_F_F_F_F_F_F_F,
										    self.h[4] + e & 0xF_F_F_F_F_F_F_F,
										)
							return ("{:08x}" * 5).format(*self.h  )






def      lowerCamelCase__       (       ):




			"""simple docstring"""


			lowerCAmelCase_      			=			B"Test String"
			assert SHAaHash(__lowerCAmelCase       ).final_hash() == hashlib.shaa(__lowerCAmelCase       ).hexdigest()  # noqa: S324






def      lowerCamelCase__       (       ):




			"""simple docstring"""


			lowerCAmelCase_      			=			argparse.ArgumentParser(description="Process some strings or files"       )
			parser.add_argument(
			    "--string"					,							dest="input_string"					,							default="Hello World!! Welcome to Cryptography"					,							help="Hash the string"					,							)
			parser.add_argument("--file"					,							dest="input_file"					,							help="Hash contents of a file"       )
			lowerCAmelCase_      			=			parser.parse_args()
			lowerCAmelCase_      			=			args.input_string
			# In any case hash input should be a bytestring
			if args.input_file:
						with open(args.input_file					,							"rb"       ) as f:
									lowerCAmelCase_      			=			f.read()
			else:
						lowerCAmelCase_      			=			bytes(__lowerCAmelCase					,							"utf-8"       )
			print(SHAaHash(__lowerCAmelCase       ).final_hash()       )


if __name__ == "__main__":
	main()
	import doctest

	doctest.testmod()





def      lowerCamelCase__       (       __lowerCAmelCase						:						int       ):




			"""simple docstring"""


			if upper_limit < 0:
						raise ValueError("Limit for the Catalan sequence must be ≥ 0"       )

			lowerCAmelCase_      			=			[0] * (upper_limit + 1)

			# Base case: C(0) = C(1) = 1
			lowerCAmelCase_      			=			1
			if upper_limit > 0:
						lowerCAmelCase_      			=			1

			# Recurrence relation: C(i) = sum(C(j).C(i-j-1)), from j = 0 to i
			for i in range(2					,							upper_limit + 1       ):
						for j in range(__lowerCAmelCase       ):
									catalan_list[i] += catalan_list[j] * catalan_list[i - j - 1]

			return catalan_list


if __name__ == "__main__":
			print("\n********* Catalan Numbers Using Dynamic Programming ************\n")
			print("\n*** Enter -1 at any time to quit ***")
			print("\nEnter the upper limit (≥ 0) for the Catalan number sequence: ", end="")
			try:
						while True:
									_A     =  int(input().strip())
									if N < 0:
												print("\n********* Goodbye!! ************")
												break
									else:
												print(f"""The Catalan numbers from 0 through {N} are:""")
												print(catalan_numbers(N))
												print("Try another upper limit for the sequence: ", end="")
			except (NameError, ValueError):
						print("\n********* Invalid input, goodbye! ************\n")

			import doctest

			doctest.testmod()



