






import argparse
import struct
import unittest





class 						SCREAMING_SNAKE_CASE				:





							"""simple docstring"""

							def __init__(  self:   Union[str, Any]		,     __A:   bytes   )    ->				None:
												_A								= data

												# Initialize hash values
												_A								= [
												    0X6_a_0_9_e_6_6_7,
												    0Xb_b_6_7_a_e_8_5,
												    0X3_c_6_e_f_3_7_2,
												    0Xa_5_4_f_f_5_3_a,
												    0X5_1_0_e_5_2_7_f,
												    0X9_b_0_5_6_8_8_c,
												    0X1_f_8_3_d_9_a_b,
												    0X5_b_e_0_c_d_1_9,
												]

												# Initialize round constants
												_A								= [
												    0X4_2_8_a_2_f_9_8,
												    0X7_1_3_7_4_4_9_1,
												    0Xb_5_c_0_f_b_c_f,
												    0Xe_9_b_5_d_b_a_5,
												    0X3_9_5_6_c_2_5_b,
												    0X5_9_f_1_1_1_f_1,
												    0X9_2_3_f_8_2_a_4,
												    0Xa_b_1_c_5_e_d_5,
												    0Xd_8_0_7_a_a_9_8,
												    0X1_2_8_3_5_b_0_1,
												    0X2_4_3_1_8_5_b_e,
												    0X5_5_0_c_7_d_c_3,
												    0X7_2_b_e_5_d_7_4,
												    0X8_0_d_e_b_1_f_e,
												    0X9_b_d_c_0_6_a_7,
												    0Xc_1_9_b_f_1_7_4,
												    0Xe_4_9_b_6_9_c_1,
												    0Xe_f_b_e_4_7_8_6,
												    0X0_f_c_1_9_d_c_6,
												    0X2_4_0_c_a_1_c_c,
												    0X2_d_e_9_2_c_6_f,
												    0X4_a_7_4_8_4_a_a,
												    0X5_c_b_0_a_9_d_c,
												    0X7_6_f_9_8_8_d_a,
												    0X9_8_3_e_5_1_5_2,
												    0Xa_8_3_1_c_6_6_d,
												    0Xb_0_0_3_2_7_c_8,
												    0Xb_f_5_9_7_f_c_7,
												    0Xc_6_e_0_0_b_f_3,
												    0Xd_5_a_7_9_1_4_7,
												    0X0_6_c_a_6_3_5_1,
												    0X1_4_2_9_2_9_6_7,
												    0X2_7_b_7_0_a_8_5,
												    0X2_e_1_b_2_1_3_8,
												    0X4_d_2_c_6_d_f_c,
												    0X5_3_3_8_0_d_1_3,
												    0X6_5_0_a_7_3_5_4,
												    0X7_6_6_a_0_a_b_b,
												    0X8_1_c_2_c_9_2_e,
												    0X9_2_7_2_2_c_8_5,
												    0Xa_2_b_f_e_8_a_1,
												    0Xa_8_1_a_6_6_4_b,
												    0Xc_2_4_b_8_b_7_0,
												    0Xc_7_6_c_5_1_a_3,
												    0Xd_1_9_2_e_8_1_9,
												    0Xd_6_9_9_0_6_2_4,
												    0Xf_4_0_e_3_5_8_5,
												    0X1_0_6_a_a_0_7_0,
												    0X1_9_a_4_c_1_1_6,
												    0X1_e_3_7_6_c_0_8,
												    0X2_7_4_8_7_7_4_c,
												    0X3_4_b_0_b_c_b_5,
												    0X3_9_1_c_0_c_b_3,
												    0X4_e_d_8_a_a_4_a,
												    0X5_b_9_c_c_a_4_f,
												    0X6_8_2_e_6_f_f_3,
												    0X7_4_8_f_8_2_e_e,
												    0X7_8_a_5_6_3_6_f,
												    0X8_4_c_8_7_8_1_4,
												    0X8_c_c_7_0_2_0_8,
												    0X9_0_b_e_f_f_f_a,
												    0Xa_4_5_0_6_c_e_b,
												    0Xb_e_f_9_a_3_f_7,
												    0Xc_6_7_1_7_8_f_2,
												]

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

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

							def       __A (  self:   Dict   )    ->				None:
												# 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'''		,     __A   )   )
																	# 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
																											) % 0X1_0_0_0_0_0_0_0_0

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

																						_A							,_A							,_A							,_A							,_A							,_A							,_A							,_A								= (
																						    g,
																						    f,
																						    e,
																						    ((d + tempa) % 0X1_0_0_0_0_0_0_0_0),
																						    c,
																						    b,
																						    a,
																						    ((tempa + tempa) % 0X1_0_0_0_0_0_0_0_0),
																						)

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

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

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



							def       __A (  self:   Optional[int]		,     __A:   int		,     __A:   int   )    ->				int:
												return 0Xf_f_f_f_f_f_f_f & (value << (32 - rotations)) | (value >> rotations)





class 						SCREAMING_SNAKE_CASE				( unittest.TestCase					):





							"""simple docstring"""

							def       __A (  self:   Dict   )    ->				None:
												import hashlib

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




def      __A					(     ):

					'''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(_lowercase					,			'''utf-8''' )

					print(SHAaaa(_lowercase ).hash )


if __name__ == "__main__":
				main()











import itertools
import string
from collections.abc import Generator, Iterable




def      __A					(     _lowercase					,			_lowercase ):

					'''simple docstring'''







					_A								= iter(_lowercase )
					while True:
										_A								= tuple(itertools.islice(_lowercase					,			_lowercase ) )
										if not chunk:
															return
										yield chunk




def      __A					(     _lowercase ):

					'''simple docstring'''







					_A								= ''''''.join([c.upper() for c in dirty if c in string.ascii_letters] )
					_A								= ''''''

					if len(_lowercase ) < 2:
										return dirty

					for i in range(len(_lowercase ) - 1 ):
										clean += dirty[i]

										if dirty[i] == dirty[i + 1]:
															clean += "X"

					clean += dirty[-1]

					if len(_lowercase ) & 1:
										clean += "X"

					return clean




def      __A					(     _lowercase ):

					'''simple docstring'''







					_A								= '''ABCDEFGHIKLMNOPQRSTUVWXYZ'''
					# we're using a list instead of a '2d' array because it makes the math
					# for setting up the table and doing the actual encoding/decoding simpler
					_A								= []

					# copy key chars into the table if they are in `alphabet` ignoring duplicates
					for char in key.upper():
										if char not in table and char in alphabet:
															table.append(_lowercase )

    # fill the rest of the table in with the remaining alphabet chars
					for char in alphabet:
										if char not in table:
															table.append(_lowercase )

					return table




def      __A					(     _lowercase					,			_lowercase ):

					'''simple docstring'''







					_A								= generate_table(_lowercase )
					_A								= prepare_input(_lowercase )
					_A								= ''''''

					# https://en.wikipedia.org/wiki/Playfair_cipher#Description
					for chara, chara in chunker(_lowercase					,			2 ):
										_A							,_A								= divmod(table.index(_lowercase )					,			5 )
										_A							,_A								= divmod(table.index(_lowercase )					,			5 )

										if rowa == rowa:
															ciphertext += table[rowa * 5 + (cola + 1) % 5]
															ciphertext += table[rowa * 5 + (cola + 1) % 5]
										elif cola == cola:
															ciphertext += table[((rowa + 1) % 5) * 5 + cola]
															ciphertext += table[((rowa + 1) % 5) * 5 + cola]
										else:  # rectangle
															ciphertext += table[rowa * 5 + cola]
															ciphertext += table[rowa * 5 + cola]

					return ciphertext




def      __A					(     _lowercase					,			_lowercase ):

					'''simple docstring'''







					_A								= generate_table(_lowercase )
					_A								= ''''''

					# https://en.wikipedia.org/wiki/Playfair_cipher#Description
					for chara, chara in chunker(_lowercase					,			2 ):
										_A							,_A								= divmod(table.index(_lowercase )					,			5 )
										_A							,_A								= divmod(table.index(_lowercase )					,			5 )

										if rowa == rowa:
															plaintext += table[rowa * 5 + (cola - 1) % 5]
															plaintext += table[rowa * 5 + (cola - 1) % 5]
										elif cola == cola:
															plaintext += table[((rowa - 1) % 5) * 5 + cola]
															plaintext += table[((rowa - 1) % 5) * 5 + cola]
										else:  # rectangle
															plaintext += table[rowa * 5 + cola]
															plaintext += table[rowa * 5 + cola]

					return plaintext



