






"""simple docstring"""




import os
import sys

from . import rsa_key_generator as rkg

lowerCamelCase__			=   128
lowerCamelCase__			=   256






def 						_SCREAMING_SNAKE_CASE							( UpperCamelCase     :	str		,				UpperCamelCase     :	int = DEFAULT_BLOCK_SIZE    ):
  A__											=							message.encode("""ascii"""    )

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






def 						_SCREAMING_SNAKE_CASE							( UpperCamelCase     :	list[int]		,				UpperCamelCase     :	int		,				UpperCamelCase     :	int = DEFAULT_BLOCK_SIZE    ):
  A__											=							[]
  for block_int in block_ints:
    A__											=							[]
    for i in range(block_size - 1		,				-1		,				-1    ):
      if len(UpperCamelCase    ) + i < message_length:
        A__											=							block_int // (BYTE_SIZE**i)
        A__											=							block_int % (BYTE_SIZE**i)
        block_message.insert(0		,				chr(UpperCamelCase    )    )
    message.extend(UpperCamelCase    )
  return "".join(UpperCamelCase    )






def 						_SCREAMING_SNAKE_CASE							( UpperCamelCase     :	str		,				UpperCamelCase     :	tuple[int, int]		,				UpperCamelCase     :	int = DEFAULT_BLOCK_SIZE    ):
  A__											=							[]
  A__						,A__											=							key

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






def 						_SCREAMING_SNAKE_CASE							( UpperCamelCase     :	list[int]		,				UpperCamelCase     :	int		,				UpperCamelCase     :	tuple[int, int]		,				UpperCamelCase     :	int = DEFAULT_BLOCK_SIZE		,				):
  A__											=							[]
  A__						,A__											=							key
  for block in encrypted_blocks:
    decrypted_blocks.append(pow(UpperCamelCase		,				UpperCamelCase		,				UpperCamelCase    )    )
  return get_text_from_blocks(UpperCamelCase		,				UpperCamelCase		,				UpperCamelCase    )






def 						_SCREAMING_SNAKE_CASE							( UpperCamelCase     :	str    ):
  with open(UpperCamelCase    ) as fo:
    A__											=							fo.read()
  A__						,A__						,A__											=							content.split(""","""    )
  return (int(UpperCamelCase    ), int(UpperCamelCase    ), int(UpperCamelCase    ))






def 						_SCREAMING_SNAKE_CASE							( UpperCamelCase     :	str		,				UpperCamelCase     :	str		,				UpperCamelCase     :	str		,				UpperCamelCase     :	int = DEFAULT_BLOCK_SIZE		,				):
  A__						,A__						,A__											=							read_key_file(UpperCamelCase    )
  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		,				UpperCamelCase    )    )

  A__											=							[str(UpperCamelCase    ) for i in encrypt_message(UpperCamelCase		,				(n, e)		,				UpperCamelCase    )]

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






def 						_SCREAMING_SNAKE_CASE							( UpperCamelCase     :	str		,				UpperCamelCase     :	str    ):
  A__						,A__						,A__											=							read_key_file(UpperCamelCase    )
  with open(UpperCamelCase    ) as fo:
    A__											=							fo.read()
  A__						,A__						,A__											=							content.split("""_"""    )
  A__											=							int(UpperCamelCase    )
  A__											=							int(UpperCamelCase    )

  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		,				UpperCamelCase    )    )

  A__											=							[]
  for block in encrypted_message.split(""","""    ):
    encrypted_blocks.append(int(UpperCamelCase    )    )

  return decrypt_message(UpperCamelCase		,				UpperCamelCase		,				(n, d)		,				UpperCamelCase    )






def 						_SCREAMING_SNAKE_CASE							( ):
  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"""		,				1024    )

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

    print("""\nEncrypted text:"""    )
    print(UpperCamelCase    )

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

    print("""\nDecryption:"""    )
    print(UpperCamelCase    )


if __name__ == "__main__":
      main()












"""simple docstring"""




from .hash_table import HashTable
from .number_theory.prime_numbers import is_prime, next_prime







class 					_UpperCamelCase		( __snake_case):






    def __init__(self						,      *lowerCamelCase__						,      **lowerCamelCase__   ):


      """simple docstring"""
      super().__init__(*lowerCamelCase__						,      **lowerCamelCase__   )






    def  A    (self						,      lowerCamelCase__						,      lowerCamelCase__   ):


      """simple docstring"""
      A__											=							(
          next_prime(value % self.size_table   )
          if not is_prime(value % self.size_table   )
          else value % self.size_table
      )  # gt = bigger than
      return next_prime_gt - (data % next_prime_gt)






    def  A    (self						,      lowerCamelCase__						,      lowerCamelCase__						,      lowerCamelCase__   ):


      """simple docstring"""
      return (increment * self.__hash_function_a(lowerCamelCase__						,      lowerCamelCase__   )) % self.size_table






    def  A    (self						,      lowerCamelCase__						,      lowerCamelCase__=None   ):


      """simple docstring"""
      A__											=							1
      A__											=							self.hash_function(lowerCamelCase__   )

      while self.values[new_key] is not None and self.values[new_key] != key:
        A__											=							(
            self.__hash_double_function(lowerCamelCase__						,      lowerCamelCase__						,      lowerCamelCase__   )
            if self.balanced_factor() >= self.lim_charge
            else None
        )
        if new_key is None:
          break
        else:
          i += 1

      return new_key




