
import argparse
import struct
import unittest





class 							A__		:
      def __init__(      self    ,  __magic_name__      ):
       lowerCamelCase		:	List[str]							=      data

       # Initialize hash values
       lowerCamelCase		:	List[str]							=      [
           0X6A09E667,
           0XBB67AE85,
           0X3C6EF372,
           0XA54FF53A,
           0X510E527F,
           0X9B05688C,
           0X1F83D9AB,
           0X5BE0CD19,
       ]

       # Initialize round constants
       lowerCamelCase		:	Dict							=      [
           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,
       ]

       lowerCamelCase		:	Optional[int]							=      self.preprocessing(self.data      )
       self.final_hash()
      @staticmethod
      def 						UpperCamelCase__							(      __magic_name__      ):
       lowerCamelCase		:	Optional[int]							=      b"""\x80""" + (b"""\x00""" * (6_3 - (len(__magic_name__      ) + 8) % 6_4))
       lowerCamelCase		:	str							=      struct.pack(""">Q"""    ,  (len(__magic_name__      ) * 8)      )
       return data + padding + big_endian_integer
      def 						UpperCamelCase__							(      self      ):
       # Convert into blocks of 64 bytes
       lowerCamelCase		:	Optional[Any]							=      [
           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
        lowerCamelCase		:	List[str]							=      list(struct.unpack(""">16L"""    ,  __magic_name__      )      )
        # add 48 0-ed integers
        words += [0] * 4_8

        lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase		:	Optional[Any]							=      self.hashes

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

          lowerCamelCase		:	str							=      (
              words[index - 1_6] + sa + words[index - 7] + sa
          ) % 0X100000000

         # Compression
         lowerCamelCase		:	List[Any]							=      self.ror(__magic_name__    ,  6      ) ^ self.ror(__magic_name__    ,  1_1      ) ^ self.ror(__magic_name__    ,  2_5      )
         lowerCamelCase		:	List[str]							=      (e & f) ^ ((~e & 0XFFFFFFFF) & g)
         lowerCamelCase		:	Optional[Any]							=      (
             h + sa + ch + self.round_constants[index] + words[index]
         ) % 0X100000000
         lowerCamelCase		:	Optional[Any]							=      self.ror(__magic_name__    ,  2      ) ^ self.ror(__magic_name__    ,  1_3      ) ^ self.ror(__magic_name__    ,  2_2      )
         lowerCamelCase		:	Optional[Any]							=      (a & b) ^ (a & c) ^ (b & c)
         lowerCamelCase		:	Optional[int]							=      (sa + maj) % 0X100000000

         lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase			,    lowerCamelCase		:	Optional[Any]							=      (
             g,
             f,
             e,
             ((d + tempa) % 0X100000000),
             c,
             b,
             a,
             ((tempa + tempa) % 0X100000000),
         )

        lowerCamelCase		:	List[str]							=      [a, b, c, d, e, f, g, h]

        # Modify final values
        lowerCamelCase		:	int							=      [
            ((element + mutated_hash_values[index]) % 0X100000000)
            for index, element in enumerate(self.hashes      )
        ]

       lowerCamelCase		:	Union[str, Any]							=      """""".join([hex(__magic_name__      )[2:].zfill(8      ) for value in self.hashes]      )






      def 						UpperCamelCase__							(      self    ,  __magic_name__    ,  __magic_name__      ):
       return 0XFFFFFFFF & (value << (3_2 - rotations)) | (value >> rotations)





class 							A__		(	unittest.TestCase):
      def 						UpperCamelCase__							(      self      ):
       import hashlib

       lowerCamelCase		:	int							=      bytes("""Test String"""    ,  """utf-8"""      )
       self.assertEqual(SHAaaa(__magic_name__      ).hash    ,  hashlib.shaaaa(__magic_name__      ).hexdigest()      )





def     _a					(						):
 import doctest

 doctest.testmod()

 lowerCamelCase		:	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		:	Optional[Any]							=      parser.parse_args()

 lowerCamelCase		:	List[Any]							=      args.input_string

 # hash input should be a bytestring
 if args.input_file:
  with open(args.input_file,	"""rb"""							) as f:
   lowerCamelCase		:	Dict							=      f.read()
 else:
  lowerCamelCase		:	List[str]							=      bytes(lowerCamelCase,	"""utf-8"""							)

 print(SHAaaa(lowerCamelCase							).hash							)


if __name__ == "__main__":
      main()






def     _a					(						lowerCamelCase = 100_0000							):
 lowerCamelCase		:	Any							=      set(range(3,	lowerCamelCase,	2							)							)
 primes.add(2							)
 for p in range(3,	lowerCamelCase,	2							):
  if p not in primes:
   continue
  primes.difference_update(set(range(p * p,	lowerCamelCase,	lowerCamelCase							)							)							)

 lowerCamelCase		:	Any							=      [float(lowerCamelCase							) for n in range(limit + 1							)]

 for p in primes:
  for n in range(lowerCamelCase,	limit + 1,	lowerCamelCase							):
   phi[n] *= 1 - 1 / p

 return int(sum(phi[2:]							)							)


if __name__ == "__main__":
      print(f'''{solution() = }''')




