






"""simple docstring"""

import argparse
import struct
import unittest


class 		__lowerCamelCase				:





		'''simple docstring'''






		def __init__(   self							:	List[Any]						,			a_							:	bytes	):
				lowerCAmelCase_   :							Optional[int]									=			data

				# Initialize hash values
				lowerCAmelCase_   :							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_   :							int									=			[
				    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_   :							Union[str, Any]									=			self.preprocessing(self.data	)
				self.final_hash()





		@staticmethod
		def    lowerCamelCase       (   a_							:	bytes	):
				lowerCAmelCase_   :							Tuple									=			b"\x80" + (b"\x00" * (63 - (len(a_	) + 8) % 64))
				lowerCAmelCase_   :							int									=			struct.pack(">Q"						,			(len(a_	) * 8)	)
				return data + padding + big_endian_integer





		def    lowerCamelCase       (   self							:	Any	):
				# 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_   :							int									=			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_   :							int									=			(
										    self.ror(words[index - 15]						,			7	)
										    ^ self.ror(words[index - 15]						,			18	)
										    ^ (words[index - 15] >> 3)
										)
										lowerCAmelCase_   :							int									=			(
										    self.ror(words[index - 2]						,			17	)
										    ^ self.ror(words[index - 2]						,			19	)
										    ^ (words[index - 2] >> 10)
										)

										lowerCAmelCase_   :							Tuple									=			(
										    words[index - 16] + sa + words[index - 7] + sa
										) % 0x1_00_00_00_00

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

								lowerCAmelCase_				,	lowerCAmelCase_				,	lowerCAmelCase_				,	lowerCAmelCase_				,	lowerCAmelCase_				,	lowerCAmelCase_				,	lowerCAmelCase_				,	lowerCAmelCase_   :							str									=			(
								    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_   :							Optional[int]									=			[
						    ((element + mutated_hash_values[index]) % 0x1_00_00_00_00)
						    for index, element in enumerate(self.hashes	)
						]

				lowerCAmelCase_   :							Optional[Any]									=			"".join([hex(a_	)[2:].zfill(8	) for value in self.hashes]	)





		def    lowerCamelCase       (   self							:	Any						,			a_							:	int						,			a_							:	int	):
				return 0xFF_FF_FF_FF & (value << (32 - rotations)) | (value >> rotations)







class 		__lowerCamelCase				( unittest.TestCase			):





		'''simple docstring'''






		def    lowerCamelCase       (   self							:	List[Any]	):
				import hashlib

				lowerCAmelCase_   :							List[str]									=			bytes("Test String"						,			"utf-8"	)
				self.assertEqual(SHAaaa(a_	).hash						,			hashlib.shaaaa(a_	).hexdigest()	)







def 		__lowerCamelCase	(  )						->    int:

		"""simple docstring"""







		import doctest

		doctest.testmod()

		lowerCAmelCase_   :							Optional[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_   :							Tuple									=			parser.parse_args()

		lowerCAmelCase_   :							Any									=			args.input_string

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

		print(SHAaaa(__UpperCamelCase       ).hash       )


if __name__ == "__main__":
					main()

def    a__       (						__UpperCamelCase ):
      if not head:
            return True
      # split the list to two parts
      SCREAMING_SNAKE_CASE_   ,       SCREAMING_SNAKE_CASE_      =     head.next, head
      while fast and fast.next:
            SCREAMING_SNAKE_CASE_      =     fast.next.next
            SCREAMING_SNAKE_CASE_      =     slow.next
      SCREAMING_SNAKE_CASE_      =     slow.next
      SCREAMING_SNAKE_CASE_      =     None  # Don't forget here! But forget still works!
      # reverse the second part
      SCREAMING_SNAKE_CASE_      =     None
      while second:
            SCREAMING_SNAKE_CASE_      =     second.next
            SCREAMING_SNAKE_CASE_      =     node
            SCREAMING_SNAKE_CASE_      =     second
            SCREAMING_SNAKE_CASE_      =     nxt
      # compare two parts
      # second part has the same or one less node
      while node:
            if node.val != head.val:
                  return False
            SCREAMING_SNAKE_CASE_      =     node.next
            SCREAMING_SNAKE_CASE_      =     head.next
      return True


def    a__       (						__UpperCamelCase ):
      if not head or not head.next:
            return True

      # 1. Get the midpoint (slow)
      SCREAMING_SNAKE_CASE_      =     SCREAMING_SNAKE_CASE_      =     SCREAMING_SNAKE_CASE_      =     head
      while fast and fast.next:
            SCREAMING_SNAKE_CASE_   ,       SCREAMING_SNAKE_CASE_      =     fast.next.next, slow.next

      # 2. Push the second half into the stack
      SCREAMING_SNAKE_CASE_      =     [slow.val]
      while slow.next:
            SCREAMING_SNAKE_CASE_      =     slow.next
            stack.append(slow.val )

      # 3. Comparison
      while stack:
            if stack.pop() != cur.val:
                  return False
            SCREAMING_SNAKE_CASE_      =     cur.next

      return True





def    a__       (						__UpperCamelCase ):
      if not head or not head.next:
            return True
      SCREAMING_SNAKE_CASE_      =     {}
      SCREAMING_SNAKE_CASE_      =     0
      while head:
            if head.val in d:
                  d[head.val].append(__UpperCamelCase )
            else:
                  SCREAMING_SNAKE_CASE_      =     [pos]
            SCREAMING_SNAKE_CASE_      =     head.next
            pos += 1
      SCREAMING_SNAKE_CASE_      =     pos - 1
      SCREAMING_SNAKE_CASE_      =     0
      for v in d.values():
            if len(__UpperCamelCase ) % 2 != 0:
                  middle += 1
            else:
                  SCREAMING_SNAKE_CASE_      =     0
                  for i in range(0   ,					len(__UpperCamelCase ) ):
                        if v[i] + v[len(__UpperCamelCase ) - 1 - step] != checksum:
                              return False
                        step += 1
            if middle > 1:
                  return False
      return True


