





import os
import sys

from . import rsa_key_generator as rkg

snake_case__									=  128
snake_case__									=  256



def _a       (			lowerCamelCase:     str      ,       lowerCamelCase:     int = DEFAULT_BLOCK_SIZE				)			->		list[int]:







      '''simple docstring'''






      __A      =       message.encode('''ascii'''				)

      __A      =       []
      for block_start in range(0      ,       len(lowerCamelCase				)      ,       lowerCamelCase				):
            __A      =       0
            for i in range(lowerCamelCase      ,       min(block_start + block_size      ,       len(lowerCamelCase				)				)				):
                  block_int += message_bytes[i] * (BYTE_SIZE ** (i % block_size))
            block_ints.append(lowerCamelCase				)
      return block_ints



def _a       (			lowerCamelCase:     list[int]      ,       lowerCamelCase:     int      ,       lowerCamelCase:     int = DEFAULT_BLOCK_SIZE				)			->		str:







      '''simple docstring'''






      __A      =       []
      for block_int in block_ints:
            __A      =       []
            for i in range(block_size - 1      ,       -1      ,       -1				):
                  if len(lowerCamelCase				) + i < message_length:
                        __A      =       block_int // (BYTE_SIZE**i)
                        __A      =       block_int % (BYTE_SIZE**i)
                        block_message.insert(0      ,       chr(lowerCamelCase				)				)
            message.extend(lowerCamelCase				)
      return "".join(lowerCamelCase				)



def _a       (			lowerCamelCase:     str      ,       lowerCamelCase:     tuple[int, int]      ,       lowerCamelCase:     int = DEFAULT_BLOCK_SIZE				)			->		list[int]:







      '''simple docstring'''






      __A      =       []
      __A     ,		__A      =       key

      for block in get_blocks_from_text(lowerCamelCase      ,       lowerCamelCase				):
            encrypted_blocks.append(pow(lowerCamelCase      ,       lowerCamelCase      ,       lowerCamelCase				)				)
      return encrypted_blocks



def _a       (			lowerCamelCase:     list[int]      ,       lowerCamelCase:     int      ,       lowerCamelCase:     tuple[int, int]      ,       lowerCamelCase:     int = DEFAULT_BLOCK_SIZE      ,       )			->		str:







      '''simple docstring'''






      __A      =       []
      __A     ,		__A      =       key
      for block in encrypted_blocks:
            decrypted_blocks.append(pow(lowerCamelCase      ,       lowerCamelCase      ,       lowerCamelCase				)				)
      return get_text_from_blocks(lowerCamelCase      ,       lowerCamelCase      ,       lowerCamelCase				)



def _a       (			lowerCamelCase:     str				)			->		tuple[int, int, int]:







      '''simple docstring'''






      with open(lowerCamelCase				) as fo:
            __A      =       fo.read()
      __A     ,		__A     ,		__A      =       content.split(''','''				)
      return (int(lowerCamelCase				), int(lowerCamelCase				), int(lowerCamelCase				))



def _a       (			lowerCamelCase:     str      ,       lowerCamelCase:     str      ,       lowerCamelCase:     str      ,       lowerCamelCase:     int = DEFAULT_BLOCK_SIZE      ,       )			->		str:







      '''simple docstring'''






      __A     ,		__A     ,		__A      =       read_key_file(lowerCamelCase				)
      if key_size < block_size * 8:
            sys.exit(
                '''ERROR: Block size is {} bits and key size is {} bits. The RSA cipher '''
                '''requires the block size to be equal to or greater than the key size. '''
                '''Either decrease the block size or use different keys.'''.format(
                    block_size * 8      ,       lowerCamelCase				)				)

      __A      =       [str(lowerCamelCase				) for i in encrypt_message(lowerCamelCase      ,       (n, e)      ,       lowerCamelCase				)]

      __A      =       ''','''.join(lowerCamelCase				)
      __A      =       F"""{len(lowerCamelCase				)}_{block_size}_{encrypted_content}"""
      with open(lowerCamelCase      ,       '''w'''				) as fo:
            fo.write(lowerCamelCase				)
      return encrypted_content



def _a       (			lowerCamelCase:     str      ,       lowerCamelCase:     str				)			->		str:







      '''simple docstring'''






      __A     ,		__A     ,		__A      =       read_key_file(lowerCamelCase				)
      with open(lowerCamelCase				) as fo:
            __A      =       fo.read()
      __A     ,		__A     ,		__A      =       content.split('''_'''				)
      __A      =       int(lowerCamelCase				)
      __A      =       int(lowerCamelCase				)

      if key_size < block_size * 8:
            sys.exit(
                '''ERROR: Block size is {} bits and key size is {} bits. The RSA cipher '''
                '''requires the block size to be equal to or greater than the key size. '''
                '''Did you specify the correct key file and encrypted file?'''.format(
                    block_size * 8      ,       lowerCamelCase				)				)

      __A      =       []
      for block in encrypted_message.split(''','''				):
            encrypted_blocks.append(int(lowerCamelCase				)				)

      return decrypt_message(lowerCamelCase      ,       lowerCamelCase      ,       (n, d)      ,       lowerCamelCase				)



def _a       (			)			->		None:







      '''simple docstring'''






      __A      =       '''encrypted_file.txt'''
      __A      =       input(r'''Encrypt\Decrypt [e\d]: '''				)

      if response.lower().startswith('''e'''				):
            __A      =       '''encrypt'''
      elif response.lower().startswith('''d'''				):
            __A      =       '''decrypt'''

      if mode == "encrypt":
            if not os.path.exists('''rsa_pubkey.txt'''				):
                  rkg.make_key_files('''rsa'''      ,       10_24				)

            __A      =       input('''\nEnter message: '''				)
            __A      =       '''rsa_pubkey.txt'''
            print(F"""Encrypting and writing to {filename}..."""				)
            __A      =       encrypt_and_write_to_file(lowerCamelCase      ,       lowerCamelCase      ,       lowerCamelCase				)

            print('''\nEncrypted text:'''				)
            print(lowerCamelCase				)

      elif mode == "decrypt":
            __A      =       '''rsa_privkey.txt'''
            print(F"""Reading from {filename} and decrypting..."""				)
            __A      =       read_from_file_and_decrypt(lowerCamelCase      ,       lowerCamelCase				)
            print('''writing decryption to rsa_decryption.txt...'''				)
            with open('''rsa_decryption.txt'''      ,       '''w'''				) as dec:
                  dec.write(lowerCamelCase				)

            print('''\nDecryption:'''				)
            print(lowerCamelCase				)


if __name__ == "__main__":
       main()












import unittest
from timeit import timeit



def _a       (			lowerCamelCase:     int      ,       lowerCamelCase:     int				)			->		int:







      '''simple docstring'''






      __A      =       first_num if first_num >= second_num else second_num
      __A      =       max_num
      while (common_mult % first_num > 0) or (common_mult % second_num > 0):
            common_mult += max_num
      return common_mult



def _a       (			lowerCamelCase:     int      ,       lowerCamelCase:     int				)			->		int:







      '''simple docstring'''






      return b if a == 0 else greatest_common_divisor(b % a      ,       lowerCamelCase				)



def _a       (			lowerCamelCase:     int      ,       lowerCamelCase:     int				)			->		int:







      '''simple docstring'''






      return first_num // greatest_common_divisor(lowerCamelCase      ,       lowerCamelCase				) * second_num



def _a       (			)			->		Tuple:







      '''simple docstring'''






      __A      =       (
          '''from __main__ import least_common_multiple_slow, least_common_multiple_fast'''
      )
      print(
          '''least_common_multiple_slow():'''      ,       timeit('''least_common_multiple_slow(1000, 999)'''      ,       setup=lowerCamelCase				)      ,       )
      print(
          '''least_common_multiple_fast():'''      ,       timeit('''least_common_multiple_fast(1000, 999)'''      ,       setup=lowerCamelCase				)      ,       )





class A_      (    unittest.TestCase     ):
   lowerCAmelCase__       =				(
       (10, 20),
       (13, 15),
       (4, 31),
       (10, 42),
       (43, 34),
       (5, 12),
       (12, 25),
       (10, 25),
       (6, 9),
   )
   lowerCAmelCase__       =				(20, 195, 124, 210, 1462, 60, 300, 50, 18)




   def _lowerCAmelCase   (self			:List[str]				)->      Union[str, Any]:
         for i, (first_num, second_num) in enumerate(self.test_inputs				):
               __A      =       least_common_multiple_slow(_UpperCamelCase					,     _UpperCamelCase				)
               __A      =       least_common_multiple_fast(_UpperCamelCase					,     _UpperCamelCase				)
               with self.subTest(i=_UpperCamelCase				):
                     self.assertEqual(_UpperCamelCase					,     self.expected_results[i]				)
                     self.assertEqual(_UpperCamelCase					,     self.expected_results[i]				)


if __name__ == "__main__":
       benchmark()
       unittest.main()





