






import argparse
import struct
import unittest


class      lowercase__     :

	def __init__(							self		,    __UpperCAmelCase       )->					Any:







							'''simple docstring'''





							lowerCAmelCase__       =						data

							# Initialize hash values
							lowerCAmelCase__       =						[
							    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__       =						[
							    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__       =						self.preprocessing(self.data       )
							self.final_hash()

	@staticmethod
	def 		UpperCAmelCase  (							__UpperCAmelCase       )->					List[Any]:







							'''simple docstring'''





							lowerCAmelCase__       =						B'\x80' + (B'\x00' * (63 - (len(UpperCAmelCase_       ) + 8) % 64))
							lowerCAmelCase__       =						struct.pack(">Q"		,    (len(UpperCAmelCase_       ) * 8)       )
							return data + padding + big_endian_integer

	def 		UpperCAmelCase  (							self       )->					str:







							'''simple docstring'''





							lowerCAmelCase__       =						[
							    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__       =						list(struct.unpack(">16L"		,    UpperCAmelCase_       )       )
													# add 48 0-ed integers
													words += [0] * 48

													lowerCAmelCase__       =						self.hashes

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

																									lowerCAmelCase__       =						(
																									    words[index - 16] + sa + words[index - 7] + sa
																									) % 0X1_00_00_00_00

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

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

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

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

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


	def 		UpperCAmelCase  (							self		,    __UpperCAmelCase		,    __UpperCAmelCase       )->					str:







							'''simple docstring'''





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





class      lowercase__     (			unittest.TestCase	):

	def 		UpperCAmelCase  (							self       )->					List[Any]:







							'''simple docstring'''





							import hashlib

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





def        _a  (     ) ->   None:
						"""simple docstring"""







						import doctest

						doctest.testmod()

						lowerCAmelCase__       =						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__       =						parser.parse_args()

						lowerCAmelCase__       =						args.input_string

						# 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(SHAaaa(lowerCamelCase_   ).hash   )


if __name__ == "__main__":
	main()














# this script reports modified .py files under the desired list of top-level sub-dirs passed as a list of arguments, e.g.:
#   python ./utils/get_modified_files.py utils src tests examples
#
# it uses git to find the forking point and which files were modified - i.e. files not under git won't be considered
# since the output of this script is fed into Makefile commands it doesn't print a newline after the results

import re
import subprocess
import sys


a_							=    subprocess.check_output('''git merge-base main HEAD'''.split()).decode('''utf-8''')
a_							=    subprocess.check_output(F"git diff --name-only {fork_point_sha}".split()).decode('''utf-8''').split()

a_							=    '''|'''.join(sys.argv[1:])
a_							=    re.compile(rF"^({joined_dirs}).*?\.py$")

a_							=    [x for x in modified_files if regex.match(x)]
print(''' '''.join(relevant_modified_files), end='''''')






