
class      UpperCamelCase    :



	def __init__(       self		):
							A__							=       {}



	def 			__A							(       self		):
							print(self.vertex		)
							for i in self.vertex:
													print(UpperCAmelCase__			,	" -> "			,	" -> ".join([str(UpperCAmelCase__		) for j in self.vertex[i]]		)		)



	def 			__A							(       self			,	UpperCAmelCase__			,	UpperCAmelCase__		):
							# check if vertex is already present,
							if from_vertex in self.vertex:
													self.vertex[from_vertex].append(UpperCAmelCase__		)
							else:
													# else make a new vertex
													A__							=       [to_vertex]



	def 			__A							(       self		):
							# visited array for storing already visited nodes
							A__							=       [False] * len(self.vertex		)

							# call the recursive helper function
							for i in range(len(self.vertex		)		):
													if not visited[i]:
																			self.dfs_recursive(UpperCAmelCase__			,	UpperCAmelCase__		)



	def 			__A							(       self			,	UpperCAmelCase__			,	UpperCAmelCase__		):
							# mark start vertex as visited
							A__							=       True

							print(UpperCAmelCase__			,	end=" "		)

							# Recur for all the vertices that are adjacent to this node
							for i in self.vertex:
													if not visited[i]:
																			self.dfs_recursive(UpperCAmelCase__			,	UpperCAmelCase__		)


if __name__ == "__main__":
						UpperCAmelCase_							:      List[Any]      =  Graph()
						g.add_edge(0, 1)
						g.add_edge(0, 2)
						g.add_edge(1, 2)
						g.add_edge(2, 0)
						g.add_edge(2, 3)
						g.add_edge(3, 3)

						g.print_graph()
						print("DFS:")
						g.dfs()

						# OUTPUT:
						# 0  ->  1 -> 2
						# 1  ->  2
						# 2  ->  0 -> 3
						# 3  ->  3
						# DFS:
						#  0 1 2 3










import argparse
import struct
import unittest






class      UpperCamelCase    :



	def __init__(       self			,	UpperCAmelCase__		):
							A__							=       data

							# Initialize hash values
							A__							=       [
							    0x6A_09E_667,
							    0xBB_67A_E85,
							    0x3C_6EF_372,
							    0xA5_4FF_53A,
							    0x51_0E5_27F,
							    0x9B_056_88C,
							    0x1F_83D_9AB,
							    0x5B_E0C_D19,
							]

							# Initialize round constants
							A__							=       [
							    0x42_8A2_F98,
							    0x71_374_491,
							    0xB5_C0F_BCF,
							    0xE9_B5D_BA5,
							    0x39_56C_25B,
							    0x59_F11_1F1,
							    0x92_3F8_2A4,
							    0xAB_1C5_ED5,
							    0xD8_07A_A98,
							    0x12_835_B01,
							    0x24_318_5BE,
							    0x55_0C7_DC3,
							    0x72_BE5_D74,
							    0x80_DEB_1FE,
							    0x9B_DC0_6A7,
							    0xC1_9BF_174,
							    0xE4_9B6_9C1,
							    0xEF_BE4_786,
							    0x0F_C19_DC6,
							    0x24_0CA_1CC,
							    0x2D_E92_C6F,
							    0x4A_748_4AA,
							    0x5C_B0A_9DC,
							    0x76_F98_8DA,
							    0x98_3E5_152,
							    0xA8_31C_66D,
							    0xB0_032_7C8,
							    0xBF_597_FC7,
							    0xC6_E00_BF3,
							    0xD5_A79_147,
							    0x06_CA6_351,
							    0x14_292_967,
							    0x27_B70_A85,
							    0x2E_1B2_138,
							    0x4D_2C6_DFC,
							    0x53_380_D13,
							    0x65_0A7_354,
							    0x76_6A0_ABB,
							    0x81_C2C_92E,
							    0x92_722_C85,
							    0xA2_BFE_8A1,
							    0xA8_1A6_64B,
							    0xC2_4B8_B70,
							    0xC7_6C5_1A3,
							    0xD1_92E_819,
							    0xD6_990_624,
							    0xF4_0E3_585,
							    0x10_6AA_070,
							    0x19_A4C_116,
							    0x1E_376_C08,
							    0x27_487_74C,
							    0x34_B0B_CB5,
							    0x39_1C0_CB3,
							    0x4E_D8A_A4A,
							    0x5B_9CC_A4F,
							    0x68_2E6_FF3,
							    0x74_8F8_2EE,
							    0x78_A56_36F,
							    0x84_C87_814,
							    0x8C_C70_208,
							    0x90_BEF_FFA,
							    0xA4_506_CEB,
							    0xBE_F9A_3F7,
							    0xC6_717_8F2,
							]

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



	@staticmethod
	def 			__A							(       UpperCAmelCase__		):
							A__							=       b"\x80" + (b"\x00" * (63 - (len(UpperCAmelCase__		) + 8) % 64))
							A__							=       struct.pack(">Q"			,	(len(UpperCAmelCase__		) * 8)		)
							return data + padding + big_endian_integer



	def 			__A							(       self		):
							# Convert into blocks of 64 bytes
							A__							=       [
							    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
													A__							=       list(struct.unpack(">16L"			,	UpperCAmelCase__		)		)
													# add 48 0-ed integers
													words += [0] * 48

													A__						,       A__						,       A__						,       A__						,       A__						,       A__						,       A__						,       A__							=       self.hashes

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

																									A__							=       (
																									    words[index - 16] + sa + words[index - 7] + sa
																									) % 0x100_000_000

																			# Compression
																			A__							=       self.ror(UpperCAmelCase__			,	6		) ^ self.ror(UpperCAmelCase__			,	11		) ^ self.ror(UpperCAmelCase__			,	25		)
																			A__							=       (e & f) ^ ((~e & 0xFF_FFF_FFF) & g)
																			A__							=       (
																			    h + sa + ch + self.round_constants[index] + words[index]
																			) % 0x100_000_000
																			A__							=       self.ror(UpperCAmelCase__			,	2		) ^ self.ror(UpperCAmelCase__			,	13		) ^ self.ror(UpperCAmelCase__			,	22		)
																			A__							=       (a & b) ^ (a & c) ^ (b & c)
																			A__							=       (sa + maj) % 0x100_000_000

																			A__						,       A__						,       A__						,       A__						,       A__						,       A__						,       A__						,       A__							=       (
																			    g,
																			    f,
																			    e,
																			    ((d + tempa) % 0x100_000_000),
																			    c,
																			    b,
																			    a,
																			    ((tempa + tempa) % 0x100_000_000),
																			)

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

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

							A__							=       "".join([hex(UpperCAmelCase__		)[2:].zfill(8		) for value in self.hashes]		)



	def 			__A							(       self			,	UpperCAmelCase__			,	UpperCAmelCase__		):
							return 0xFF_FFF_FFF & (value << (32 - rotations)) | (value >> rotations)






class      UpperCamelCase    (						unittest.TestCase     ):



	def 			__A							(       self		):
							import hashlib

							A__							=       bytes("Test String"			,	"utf-8"		)
							self.assertEqual(SHAaaa(UpperCAmelCase__		).hash			,	hashlib.shaaaa(UpperCAmelCase__		).hexdigest()		)





def  UpperCamelCase						(       )->       None:





						"""simple docstring"""





						import doctest

						doctest.testmod()

						A__							=       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"    )

						A__							=       parser.parse_args()

						A__							=       args.input_string

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

						print(SHAaaa(_A    ).hash    )


if __name__ == "__main__":
						main()





