



"""simple docstring"""


import argparse
import struct
import unittest
class 			_a :
			"""simple docstring"""



			def __init__(		self     :    List[Any]				,   __UpperCamelCase     :    bytes   )->None:
							_UpperCAmelCase					=    data

							# Initialize hash values
							_UpperCAmelCase					=    [
							    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
							_UpperCAmelCase					=    [
							    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,
							]

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



			@staticmethod
			def  lowercase__						(		__UpperCamelCase     :    bytes   )->bytes:
							_UpperCAmelCase					=    B'''\x80''' + (B'''\x00''' * (6_3 - (len(__UpperCamelCase   ) + 8) % 6_4))
							_UpperCAmelCase					=    struct.pack('''>Q'''				,   (len(__UpperCamelCase   ) * 8)   )
							return data + padding + big_endian_integer



			def  lowercase__						(		self     :    Tuple   )->None:
							# Convert into blocks of 64 bytes
							_UpperCAmelCase					=    [
							    self.preprocessed_data[x : x + 6_4]
							    for x in range(0				,   len(self.preprocessed_data   )				,   6_4   )
							]

							for block in self.blocks:
											# Convert the given block into a list of 4 byte integers
											_UpperCAmelCase					=    list(struct.unpack('''>16L'''				,   __UpperCamelCase   )   )
											# add 48 0-ed integers
											words += [0] * 4_8

											_UpperCAmelCase		,						_UpperCAmelCase		,						_UpperCAmelCase		,						_UpperCAmelCase		,						_UpperCAmelCase		,						_UpperCAmelCase		,						_UpperCAmelCase		,						_UpperCAmelCase					=    self.hashes

											for index in range(0				,   6_4   ):
															if index > 1_5:
																			# modify the zero-ed indexes at the end of the array
																			_UpperCAmelCase					=    (
																			    self.ror(words[index - 1_5]				,   7   )
																			    ^ self.ror(words[index - 1_5]				,   1_8   )
																			    ^ (words[index - 1_5] >> 3)
																			)
																			_UpperCAmelCase					=    (
																			    self.ror(words[index - 2]				,   1_7   )
																			    ^ self.ror(words[index - 2]				,   1_9   )
																			    ^ (words[index - 2] >> 1_0)
																			)

																			_UpperCAmelCase					=    (
																			    words[index - 1_6] + sa + words[index - 7] + sa
																			) % 0X1_00_00_00_00

															# Compression
															_UpperCAmelCase					=    self.ror(__UpperCamelCase				,   6   ) ^ self.ror(__UpperCamelCase				,   1_1   ) ^ self.ror(__UpperCamelCase				,   2_5   )
															_UpperCAmelCase					=    (e & f) ^ ((~e & 0XFF_FF_FF_FF) & g)
															_UpperCAmelCase					=    (
															    h + sa + ch + self.round_constants[index] + words[index]
															) % 0X1_00_00_00_00
															_UpperCAmelCase					=    self.ror(__UpperCamelCase				,   2   ) ^ self.ror(__UpperCamelCase				,   1_3   ) ^ self.ror(__UpperCamelCase				,   2_2   )
															_UpperCAmelCase					=    (a & b) ^ (a & c) ^ (b & c)
															_UpperCAmelCase					=    (sa + maj) % 0X1_00_00_00_00

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

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

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

							_UpperCAmelCase					=    ''''''.join([hex(__UpperCamelCase   )[2:].zfill(8   ) for value in self.hashes]   )



			def  lowercase__						(		self     :    str				,   __UpperCamelCase     :    int				,   __UpperCamelCase     :    int   )->int:
							return 0XFF_FF_FF_FF & (value << (3_2 - rotations)) | (value >> rotations)



class 			_a (					unittest.TestCase):
			"""simple docstring"""



			def  lowercase__						(		self     :    Any   )->None:
							import hashlib

							_UpperCAmelCase					=    bytes('''Test String'''				,   '''utf-8'''   )
							self.assertEqual(SHAaaa(__UpperCamelCase   ).hash				,   hashlib.shaaaa(__UpperCamelCase   ).hexdigest()   )







def  lowercase	(      ):






				'''simple docstring'''



				import doctest

				doctest.testmod()

				_UpperCAmelCase					=    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'''				)

				_UpperCAmelCase					=    parser.parse_args()

				_UpperCAmelCase					=    args.input_string

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

				print(SHAaaa(_SCREAMING_SNAKE_CASE				).hash				)


if __name__ == "__main__":
					main()








"""simple docstring"""


import operator







def  lowercase	(      _SCREAMING_SNAKE_CASE   :						list					,     _SCREAMING_SNAKE_CASE   :						bool = False					,     _SCREAMING_SNAKE_CASE   :						list | None = None				):






				'''simple docstring'''



				_UpperCAmelCase					=    operator.lt if reverse else operator.gt
				_UpperCAmelCase					=    solution or []

				if not arr:
								return solution

				_UpperCAmelCase					=    [arr.pop(0				)]
				for i, item in enumerate(_SCREAMING_SNAKE_CASE				):
								if _operator(_SCREAMING_SNAKE_CASE					,     sublist[-1]				):
												sublist.append(_SCREAMING_SNAKE_CASE				)
												arr.pop(_SCREAMING_SNAKE_CASE				)

    #  merging sublist into solution list
				if not solution:
								solution.extend(_SCREAMING_SNAKE_CASE				)
				else:
								while sublist:
												_UpperCAmelCase					=    sublist.pop(0				)
												for i, xx in enumerate(_SCREAMING_SNAKE_CASE				):
																if not _operator(_SCREAMING_SNAKE_CASE					,     _SCREAMING_SNAKE_CASE				):
																				solution.insert(_SCREAMING_SNAKE_CASE					,     _SCREAMING_SNAKE_CASE				)
																				break
												else:
																solution.append(_SCREAMING_SNAKE_CASE				)

				strand_sort(_SCREAMING_SNAKE_CASE					,     _SCREAMING_SNAKE_CASE					,     _SCREAMING_SNAKE_CASE				)
				return solution


if __name__ == "__main__":
					assert strand_sort([4, 3, 5, 1, 2]) == [1, 2, 3, 4, 5]
					assert strand_sort([4, 3, 5, 1, 2], reverse=True) == [5, 4, 3, 2, 1]



