



"""simple docstring"""






import argparse
import struct
import unittest



class      A__  :




	'''simple docstring'''





	def __init__(	self:						str			,     _SCREAMING_SNAKE_CASE:						bytes)							->			None:

				"""simple docstring"""

				__lowerCAmelCase :    List[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 :    List[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 :    Tuple				=			self.preprocessing(self.data)
				self.final_hash()

	@staticmethod
	def 				_SCREAMING_SNAKE_CASE  (	_SCREAMING_SNAKE_CASE:						bytes)							->			bytes:

				"""simple docstring"""

				__lowerCAmelCase :    int				=			b"\x80" + (b"\x00" * (63 - (len(_SCREAMING_SNAKE_CASE) + 8) % 64))
				__lowerCAmelCase :    Union[str, Any]				=			struct.pack(">Q"			,     (len(_SCREAMING_SNAKE_CASE) * 8))
				return data + padding + big_endian_integer

	def 				_SCREAMING_SNAKE_CASE  (	self:						Dict)							->			None:

				"""simple docstring"""

				__lowerCAmelCase :    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 :    Dict				=			list(struct.unpack(">16L"			,     _SCREAMING_SNAKE_CASE))
							# 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 :    Optional[Any]				=			(
													    self.ror(words[index - 15]			,     7)
													    ^ self.ror(words[index - 15]			,     18)
													    ^ (words[index - 15] >> 3)
													)
													__lowerCAmelCase :    Union[str, Any]				=			(
													    self.ror(words[index - 2]			,     17)
													    ^ self.ror(words[index - 2]			,     19)
													    ^ (words[index - 2] >> 10)
													)

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

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

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

							__lowerCAmelCase :    Optional[int]				=			[a, b, c, d, e, f, g, h]

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

				__lowerCAmelCase :    Dict				=			"".join([hex(_SCREAMING_SNAKE_CASE)[2:].zfill(8) for value in self.hashes])







	def 				_SCREAMING_SNAKE_CASE  (	self:						Optional[int]			,     _SCREAMING_SNAKE_CASE:						int			,     _SCREAMING_SNAKE_CASE:						int)							->			int:

				"""simple docstring"""

				return 0XFF_FF_FF_FF & (value << (32 - rotations)) | (value >> rotations)






class      A__  (    unittest.TestCase				):




	'''simple docstring'''





	def 				_SCREAMING_SNAKE_CASE  (	self:						Union[str, Any])							->			None:

				"""simple docstring"""

				import hashlib

				__lowerCAmelCase :    Union[str, Any]				=			bytes("Test String"			,     "utf-8")
				self.assertEqual(SHAaaa(_SCREAMING_SNAKE_CASE).hash			,     hashlib.shaaaa(_SCREAMING_SNAKE_CASE).hexdigest())






def      _lowercase							(    )		->  None:
			import doctest

			doctest.testmod()

			__lowerCAmelCase :    int				=			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 :    Tuple				=			args.input_string

			# hash input should be a bytestring
			if args.input_file:
						with open(args.input_file   ,"rb"      ) as f:
									__lowerCAmelCase :    Union[str, Any]				=			f.read()
			else:
						__lowerCAmelCase :    Optional[Any]				=			bytes(__snake_case   ,"utf-8"      )

			print(SHAaaa(__snake_case      ).hash      )


if __name__ == "__main__":
	main()




"""simple docstring"""






from math import factorial



class      A__  :




	'''simple docstring'''





	def __init__(	self:						str			,     _SCREAMING_SNAKE_CASE:						Tuple			,     _SCREAMING_SNAKE_CASE:						Any)							->			str:

				"""simple docstring"""

				__lowerCAmelCase :    str				=			real
				if isinstance(_SCREAMING_SNAKE_CASE			,     _SCREAMING_SNAKE_CASE):
							__lowerCAmelCase :    Optional[int]				=			[1] * rank
				else:
							__lowerCAmelCase :    Optional[Any]				=			rank

	def __repr__(	self:						Optional[int])							->			List[str]:

				"""simple docstring"""

				return (
				    F"""{self.real}+"""
				    F"""{'+'.join(str(_SCREAMING_SNAKE_CASE)+'E'+str(n+1)for n,dual in enumerate(self.duals))}"""
				)

	def 				_SCREAMING_SNAKE_CASE  (	self:						List[str])							->			Union[str, Any]:

				"""simple docstring"""

				__lowerCAmelCase :    List[str]				=			self.duals.copy()
				while cur[-1] == 0:
							cur.pop(-1)
				return Dual(self.real			,     _SCREAMING_SNAKE_CASE)

	def __add__(	self:						Optional[int]			,     _SCREAMING_SNAKE_CASE:						Tuple)							->			Union[str, Any]:

				"""simple docstring"""

				if not isinstance(_SCREAMING_SNAKE_CASE			,     _SCREAMING_SNAKE_CASE):
							return Dual(self.real + other			,     self.duals)
				__lowerCAmelCase :    int				=			self.duals.copy()
				__lowerCAmelCase :    List[Any]				=			other.duals.copy()
				if len(_SCREAMING_SNAKE_CASE) > len(_SCREAMING_SNAKE_CASE):
							o_dual.extend([1] * (len(_SCREAMING_SNAKE_CASE) - len(_SCREAMING_SNAKE_CASE)))
				elif len(_SCREAMING_SNAKE_CASE) < len(_SCREAMING_SNAKE_CASE):
							s_dual.extend([1] * (len(_SCREAMING_SNAKE_CASE) - len(_SCREAMING_SNAKE_CASE)))
				__lowerCAmelCase :    Tuple				=			[]
				for i in range(len(_SCREAMING_SNAKE_CASE)):
							new_duals.append(s_dual[i] + o_dual[i])
				return Dual(self.real + other.real			,     _SCREAMING_SNAKE_CASE)

	SCREAMING_SNAKE_CASE        =      __add__

	def __sub__(	self:						Dict			,     _SCREAMING_SNAKE_CASE:						str)							->			Optional[Any]:

				"""simple docstring"""

				return self + other * -1

	def __mul__(	self:						str			,     _SCREAMING_SNAKE_CASE:						Tuple)							->			Optional[int]:

				"""simple docstring"""

				if not isinstance(_SCREAMING_SNAKE_CASE			,     _SCREAMING_SNAKE_CASE):
							__lowerCAmelCase :    List[Any]				=			[]
							for i in self.duals:
										new_duals.append(i * other)
							return Dual(self.real * other			,     _SCREAMING_SNAKE_CASE)
				__lowerCAmelCase :    List[str]				=			[0] * (len(self.duals) + len(other.duals) + 1)
				for i, item in enumerate(self.duals):
							for j, jtem in enumerate(other.duals):
										new_duals[i + j + 1] += item * jtem
				for k in range(len(self.duals)):
							new_duals[k] += self.duals[k] * other.real
				for index in range(len(other.duals)):
							new_duals[index] += other.duals[index] * self.real
				return Dual(self.real * other.real			,     _SCREAMING_SNAKE_CASE)

	SCREAMING_SNAKE_CASE        =      __mul__

	def __truediv__(	self:						Any			,     _SCREAMING_SNAKE_CASE:						str)							->			Dict:

				"""simple docstring"""

				if not isinstance(_SCREAMING_SNAKE_CASE			,     _SCREAMING_SNAKE_CASE):
							__lowerCAmelCase :    List[str]				=			[]
							for i in self.duals:
										new_duals.append(i / other)
							return Dual(self.real / other			,     _SCREAMING_SNAKE_CASE)
				raise ValueError

	def __floordiv__(	self:						List[Any]			,     _SCREAMING_SNAKE_CASE:						Tuple)							->			str:

				"""simple docstring"""

				if not isinstance(_SCREAMING_SNAKE_CASE			,     _SCREAMING_SNAKE_CASE):
							__lowerCAmelCase :    str				=			[]
							for i in self.duals:
										new_duals.append(i // other)
							return Dual(self.real // other			,     _SCREAMING_SNAKE_CASE)
				raise ValueError







	def __pow__(	self:						Optional[Any]			,     _SCREAMING_SNAKE_CASE:						Tuple)							->			List[Any]:

				"""simple docstring"""

				if n < 0 or isinstance(_SCREAMING_SNAKE_CASE			,     _SCREAMING_SNAKE_CASE):
							raise ValueError("power must be a positive integer")
				if n == 0:
							return 1
				if n == 1:
							return self
				__lowerCAmelCase :    List[Any]				=			self
				for _ in range(n - 1):
							x *= self
				return x






def      _lowercase							(    __snake_case   ,__snake_case   ,__snake_case      )		->  Any:
			if not callable(__snake_case      ):
						raise ValueError("differentiate() requires a function as input for func"      )
			if not isinstance(__snake_case   ,(float, int)      ):
						raise ValueError("differentiate() requires a float as input for position"      )
			if not isinstance(__snake_case   ,__snake_case      ):
						raise ValueError("differentiate() requires an int as input for order"      )
			__lowerCAmelCase :    Any				=			Dual(__snake_case   ,1      )
			__lowerCAmelCase :    Tuple				=			func(__snake_case      )
			if order == 0:
						return result.real
			return result.duals[order - 1] * factorial(__snake_case      )


if __name__ == "__main__":
	import doctest

	doctest.testmod()


	def      _lowercase							(    __snake_case      )		->  Tuple:
				return y**2 * y**4





	print(differentiate(f, 9, 2))