






"""simple docstring"""





import argparse
import struct
import unittest


class      _lowercase :


      def __init__(    self				:	str							,   a				:	bytes						):





            """simple docstring"""







            __snake_case      :    List[Any]  			=data

            # Initialize hash values
            __snake_case      :    Optional[Any]  			=[
                0x6A09E667,
                0xBB67AE85,
                0x3C6EF372,
                0xA54FF53A,
                0x510E527F,
                0x9B05688C,
                0x1F83D9AB,
                0x5BE0CD19,
            ]

            # Initialize round constants
            __snake_case      :    List[str]  			=[
                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,
            ]

            __snake_case      :    List[Any]  			=self.preprocessing(self.data						)
            self.final_hash()


      @staticmethod
      def _UpperCamelCase						(    a				:	bytes						):





            """simple docstring"""







            __snake_case      :    int  			=b'''\x80''' + (b'''\x00''' * (6_3 - (len(a						) + 8) % 6_4))
            __snake_case      :    str  			=struct.pack('''>Q'''							,   (len(a						) * 8)						)
            return data + padding + big_endian_integer


      def _UpperCamelCase						(    self				:	List[str]						):





            """simple docstring"""







            __snake_case      :    Tuple  			=[
                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
                  __snake_case      :    Dict  			=list(struct.unpack('''>16L'''							,   a						)						)
                  # add 48 0-ed integers
                  words += [0] * 4_8

                  __snake_case			,				__snake_case			,				__snake_case			,				__snake_case			,				__snake_case			,				__snake_case			,				__snake_case			,				__snake_case      :    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
                              __snake_case      :    Union[str, Any]  			=(
                                  self.ror(words[index - 1_5]							,   7						)
                                  ^ self.ror(words[index - 1_5]							,   1_8						)
                                  ^ (words[index - 1_5] >> 3)
                              )
                              __snake_case      :    Any  			=(
                                  self.ror(words[index - 2]							,   1_7						)
                                  ^ self.ror(words[index - 2]							,   1_9						)
                                  ^ (words[index - 2] >> 1_0)
                              )

                              __snake_case      :    Any  			=(
                                  words[index - 1_6] + sa + words[index - 7] + sa
                              ) % 0x100000000

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

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

                  __snake_case      :    Optional[Any]  			=[a, b, c, d, e, f, g, h]

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

            __snake_case      :    Optional[int]  			=''''''.join([hex(a						)[2:].zfill(8						) for value in self.hashes]						)







      def _UpperCamelCase						(    self				:	Union[str, Any]							,   a				:	int							,   a				:	int						):





            """simple docstring"""







            return 0xFFFFFFFF & (value << (3_2 - rotations)) | (value >> rotations)



class      _lowercase (     unittest.TestCase						):


      def _UpperCamelCase						(    self				:	str						):





            """simple docstring"""







            import hashlib

            __snake_case      :    Dict  			=bytes('''Test String'''							,   '''utf-8'''						)
            self.assertEqual(SHAaaa(a						).hash							,   hashlib.shaaaa(a						).hexdigest()						)



def     __lowercase					(    )					->					None:
      import doctest

      doctest.testmod()

      __snake_case      :    Dict  			=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''' )

      __snake_case      :    str  			=parser.parse_args()

      __snake_case      :    Tuple  			=args.input_string

      # hash input should be a bytestring
      if args.input_file:
            with open(args.input_file       ,		'''rb''' ) as f:
                  __snake_case      :    Union[str, Any]  			=f.read()
      else:
            __snake_case      :    int  			=bytes(a       ,		'''utf-8''' )

      print(SHAaaa(a ).hash )


if __name__ == "__main__":
    main()










"""simple docstring"""





from math import atan, cos, radians, sin, tan

from .haversine_distance import haversine_distance

UpperCamelCase_	:				Optional[Any]										= 6_37_81_37.0
UpperCamelCase_	:				Optional[Any]										= 6_35_67_52.31_42_45
UpperCamelCase_	:				Union[str, Any]										= 6378137



def     __lowercase					(    a :				float       ,		a :				float       ,		a :				float       ,		a :				float )					->					float:
      __snake_case      :    Optional[Any]  			=(AXIS_A - AXIS_B) / AXIS_A
      # Parametric latitudes
      # https://en.wikipedia.org/wiki/Latitude#Parametric_(or_reduced)_latitude
      __snake_case      :    List[str]  			=atan((1 - flattening) * tan(radians(a ) ) )
      __snake_case      :    Any  			=atan((1 - flattening) * tan(radians(a ) ) )

      # Compute central angle between two points
      # using haversine theta. sigma =  haversine_distance / equatorial radius
      __snake_case      :    Optional[Any]  			=haversine_distance(a       ,		a       ,		a       ,		a ) / EQUATORIAL_RADIUS

      # Intermediate P and Q values
      __snake_case      :    List[str]  			=(b_lata + b_lata) / 2
      __snake_case      :    Dict  			=(b_lata - b_lata) / 2

      # Intermediate X value
      # X = (sigma - sin(sigma)) * sin^2Pcos^2Q / cos^2(sigma/2)
      __snake_case      :    Optional[int]  			=(sin(a ) ** 2) * (cos(a ) ** 2)
      __snake_case      :    Any  			=cos(sigma / 2 ) ** 2
      __snake_case      :    Optional[Any]  			=(sigma - sin(a )) * (x_numerator / x_demonimator)

      # Intermediate Y value
      # Y = (sigma + sin(sigma)) * cos^2Psin^2Q / sin^2(sigma/2)
      __snake_case      :    Tuple  			=(cos(a ) ** 2) * (sin(a ) ** 2)
      __snake_case      :    Dict  			=sin(sigma / 2 ) ** 2
      __snake_case      :    Tuple  			=(sigma + sin(a )) * (y_numerator / y_denominator)

      return EQUATORIAL_RADIUS * (sigma - ((flattening / 2) * (x_value + y_value)))


if __name__ == "__main__":
    import doctest

    doctest.testmod()


