



"""simple docstring"""


import argparse
import struct
import unittest







class       A_			:



						"""simple docstring"""






						def __init__(					self :int   ,  lowercase_ :bytes					)				->			None:
												UpperCAmelCase             = data

												# Initialize hash values
												UpperCAmelCase             = [
												    0x6A09E667,
												    0xBB67AE85,
												    0x3C6EF372,
												    0xA54FF53A,
												    0x510E527F,
												    0x9B05688C,
												    0x1F83D9AB,
												    0x5BE0CD19,
												]

												# Initialize round constants
												UpperCAmelCase             = [
												    0x428A2F98,
												    0x71374491,
												    0xB5C0FBCF,
												    0xE9B5DBA5,
												    0x3956C25B,
												    0x59F111F1,
												    0x923F82A4,
												    0xAB1C5ED5,
												    0xD807AA98,
												    0x12835B01,
												    0x243185BE,
												    0x550C7DC3,
												    0x72BE5D74,
												    0x80DEB1FE,
												    0x9BDC06A7,
												    0xC19BF174,
												    0xE49B69C1,
												    0xEFBE4786,
												    0x0FC19DC6,
												    0x240CA1CC,
												    0x2DE92C6F,
												    0x4A7484AA,
												    0x5CB0A9DC,
												    0x76F988DA,
												    0x983E5152,
												    0xA831C66D,
												    0xB00327C8,
												    0xBF597FC7,
												    0xC6E00BF3,
												    0xD5A79147,
												    0x06CA6351,
												    0x14292967,
												    0x27B70A85,
												    0x2E1B2138,
												    0x4D2C6DFC,
												    0x53380D13,
												    0x650A7354,
												    0x766A0ABB,
												    0x81C2C92E,
												    0x92722C85,
												    0xA2BFE8A1,
												    0xA81A664B,
												    0xC24B8B70,
												    0xC76C51A3,
												    0xD192E819,
												    0xD6990624,
												    0xF40E3585,
												    0x106AA070,
												    0x19A4C116,
												    0x1E376C08,
												    0x2748774C,
												    0x34B0BCB5,
												    0x391C0CB3,
												    0x4ED8AA4A,
												    0x5B9CCA4F,
												    0x682E6FF3,
												    0x748F82EE,
												    0x78A5636F,
												    0x84C87814,
												    0x8CC70208,
												    0x90BEFFFA,
												    0xA4506CEB,
												    0xBEF9A3F7,
												    0xC67178F2,
												]

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






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






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

																		UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase             = self.hashes

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

																														UpperCAmelCase             = (
																														    words[index - 16] + sa + words[index - 7] + sa
																														) % 0x100000000

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

																								UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase      ,    UpperCAmelCase             = (
																								    g,
																								    f,
																								    e,
																								    ((d + tempa) % 0x100000000),
																								    c,
																								    b,
																								    a,
																								    ((tempa + tempa) % 0x100000000),
																								)

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

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

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






						def 	UpperCAmelCase__     (					self :Dict   ,  lowercase_ :int   ,  lowercase_ :int					)				->			int:
												return 0xFFFFFFFF & (value << (32 - rotations)) | (value >> rotations)







class       A_			(     unittest.TestCase				):



						"""simple docstring"""






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

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


def  _lowerCAmelCase      (   ):
						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(lowercase_		,	'utf-8'						)

						print(SHAaaa(lowercase_						).hash						)


if __name__ == "__main__":
				main()












'''simple docstring'''
from __future__ import annotations

from typing import Any

class      snake_case     (    __lowerCamelCase       ):




 """simple docstring"""



 pass






class      snake_case     :




 """simple docstring"""



 def __init__(       self       :							List[Any]							,	__A       :							Any	):
        __UpperCamelCase       =  data
        __UpperCamelCase       =  None






 def __iter__(       self       :							Optional[Any]	):
        __UpperCamelCase       =  self
        __UpperCamelCase       =  []
        while node:
               if node in visited:
                      raise ContainsLoopError
               visited.append(__A	)
               yield node.data
               __UpperCamelCase       =  node.next_node






 @property
 def        _lowerCamelCase					(       self       :							List[str]	):
        try:
               list(self	)
               return False
        except ContainsLoopError:
               return True


if __name__ == "__main__":
    a__							:							Dict =Node(1)
    a__							:							Optional[int] =Node(2)
    a__							:							List[str] =Node(3)
    a__							:							Optional[int] =Node(4)
    print(root_node.has_loop)  # False
    a__							:							str =root_node.next_node
    print(root_node.has_loop)  # True

    a__							:							Optional[int] =Node(5)
    a__							:							List[Any] =Node(6)
    a__							:							int =Node(5)
    a__							:							Tuple =Node(6)
    print(root_node.has_loop)  # False

    a__							:							str =Node(1)
    print(root_node.has_loop)  # False
