
'''simple docstring'''




import argparse
import struct
import unittest





class 					A							:





     def __init__(				self		,     SCREAMING_SNAKE_CASE      )					->							None:






         """simple docstring"""






         A			:  Optional[Any]   =		data

         # Initialize hash values
         A			:  Any   =		[
             0X6A_09E_667,
             0XBB_67A_E85,
             0X3C_6EF_372,
             0XA5_4FF_53A,
             0X51_0E5_27F,
             0X9B_056_88C,
             0X1F_83D_9AB,
             0X5B_E0C_D19,
         ]

         # Initialize round constants
         A			:  Optional[int]   =		[
             0X42_8A2_F98,
             0X71_374_491,
             0XB5_C0F_BCF,
             0XE9_B5D_BA5,
             0X39_56C_25B,
             0X59_F11_1F1,
             0X92_3F8_2A4,
             0XAB_1C5_ED5,
             0XD8_07A_A98,
             0X12_835_B01,
             0X24_318_5BE,
             0X55_0C7_DC3,
             0X72_BE5_D74,
             0X80_DEB_1FE,
             0X9B_DC0_6A7,
             0XC1_9BF_174,
             0XE4_9B6_9C1,
             0XEF_BE4_786,
             0X0F_C19_DC6,
             0X24_0CA_1CC,
             0X2D_E92_C6F,
             0X4A_748_4AA,
             0X5C_B0A_9DC,
             0X76_F98_8DA,
             0X98_3E5_152,
             0XA8_31C_66D,
             0XB0_032_7C8,
             0XBF_597_FC7,
             0XC6_E00_BF3,
             0XD5_A79_147,
             0X06_CA6_351,
             0X14_292_967,
             0X27_B70_A85,
             0X2E_1B2_138,
             0X4D_2C6_DFC,
             0X53_380_D13,
             0X65_0A7_354,
             0X76_6A0_ABB,
             0X81_C2C_92E,
             0X92_722_C85,
             0XA2_BFE_8A1,
             0XA8_1A6_64B,
             0XC2_4B8_B70,
             0XC7_6C5_1A3,
             0XD1_92E_819,
             0XD6_990_624,
             0XF4_0E3_585,
             0X10_6AA_070,
             0X19_A4C_116,
             0X1E_376_C08,
             0X27_487_74C,
             0X34_B0B_CB5,
             0X39_1C0_CB3,
             0X4E_D8A_A4A,
             0X5B_9CC_A4F,
             0X68_2E6_FF3,
             0X74_8F8_2EE,
             0X78_A56_36F,
             0X84_C87_814,
             0X8C_C70_208,
             0X90_BEF_FFA,
             0XA4_506_CEB,
             0XBE_F9A_3F7,
             0XC6_717_8F2,
         ]

         A			:  Any   =		self.preprocessing(self.data      )
         self.final_hash()





     @staticmethod
     def 							__lowerCAmelCase				(				SCREAMING_SNAKE_CASE      )					->							bytes:






         """simple docstring"""






         A			:  int   =		b'''\x80''' + (b'''\x00''' * (63 - (len(SCREAMING_SNAKE_CASE      ) + 8) % 64))
         A			:  List[str]   =		struct.pack('''>Q'''		,     (len(SCREAMING_SNAKE_CASE      ) * 8)      )
         return data + padding + big_endian_integer





     def 							__lowerCAmelCase				(				self      )					->							None:






         """simple docstring"""






         A			:  int   =		[
             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			:  Any   =		list(struct.unpack('''>16L'''		,     SCREAMING_SNAKE_CASE      )      )
             # add 48 0-ed integers
             words += [0] * 48

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

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

                     A			:  Optional[int]   =		(
                         words[index - 16] + sa + words[index - 7] + sa
                     ) % 0X100_000_000

                 # Compression
                 A			:  int   =		self.ror(SCREAMING_SNAKE_CASE		,     6      ) ^ self.ror(SCREAMING_SNAKE_CASE		,     11      ) ^ self.ror(SCREAMING_SNAKE_CASE		,     25      )
                 A			:  str   =		(e & f) ^ ((~e & 0XFF_FFF_FFF) & g)
                 A			:  Dict   =		(
                     h + sa + ch + self.round_constants[index] + words[index]
                 ) % 0X100_000_000
                 A			:  Tuple   =		self.ror(SCREAMING_SNAKE_CASE		,     2      ) ^ self.ror(SCREAMING_SNAKE_CASE		,     13      ) ^ self.ror(SCREAMING_SNAKE_CASE		,     22      )
                 A			:  int   =		(a & b) ^ (a & c) ^ (b & c)
                 A			:  List[Any]   =		(sa + maj) % 0X100_000_000

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

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

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

         A			:  Tuple   =		''''''.join([hex(SCREAMING_SNAKE_CASE      )[2:].zfill(8      ) for value in self.hashes]      )





     def 							__lowerCAmelCase				(				self		,     SCREAMING_SNAKE_CASE		,     SCREAMING_SNAKE_CASE      )					->							int:






         """simple docstring"""






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





class 					A							(				unittest.TestCase		):





     def 							__lowerCAmelCase				(				self      )					->							None:






         """simple docstring"""






         import hashlib

         A			:  Union[str, Any]   =		bytes('''Test String'''		,     '''utf-8'''      )
         self.assertEqual(SHAaaa(SCREAMING_SNAKE_CASE      ).hash		,     hashlib.shaaaa(SCREAMING_SNAKE_CASE      ).hexdigest()      )







def 						lowerCAmelCase_							(  ):




    '''simple docstring'''



    import doctest

    doctest.testmod()

    A			:  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'''		)

    A			:  int   =		parser.parse_args()

    A			:  List[str]   =		args.input_string

    # hash input should be a bytestring
    if args.input_file:
        with open(args.input_file						,							'''rb'''		) as f:
            A			:  Any   =		f.read()
    else:
        A			:  Any   =		bytes(snake_case__						,							'''utf-8'''		)

    print(SHAaaa(snake_case__		).hash		)


if __name__ == "__main__":
      main()






'''simple docstring'''




lowercase     :							dict[str, float]       						=     {
    "joule": 1.0,
    "kilojoule": 10_00,
    "megajoule": 1_00_00_00,
    "gigajoule": 10_00_00_00_00,
    "wattsecond": 1.0,
    "watthour": 36_00,
    "kilowatthour": 3_60_00_00,
    "newtonmeter": 1.0,
    "calorie_nutr": 41_86.8,
    "kilocalorie_nutr": 4_18_68_00.00,
    "electronvolt": 1.6_02_17_66_34e-19,
    "britishthermalunit_it": 10_55.0_55_85,
    "footpound": 1.35_58_18,
}







def 						lowerCAmelCase_							(  snake_case__						,							snake_case__						,							snake_case__		):




    '''simple docstring'''



    if to_type not in ENERGY_CONVERSION or from_type not in ENERGY_CONVERSION:
        A			:  int   =		(
            F'Incorrect \'from_type\' or \'to_type\' value: {from_type!r}, {to_type!r}\n'
            F'Valid values are: {", ".join(snake_case__		)}'
        )
        raise ValueError(snake_case__		)
    return value * ENERGY_CONVERSION[from_type] / ENERGY_CONVERSION[to_type]


if __name__ == "__main__":
      import doctest

      doctest.testmod()




