

"""simple docstring"""
import string

import numpy




def 					a__						(						lowerCAmelCase			,	lowerCAmelCase    )	-> int:
      return b if a == 0 else greatest_common_divisor(b % a			,	lowerCAmelCase    )

class       lowerCamelCase	:


  '''simple docstring'''







  SCREAMING_SNAKE_CASE					      =  string.ascii_uppercase + string.digits
  # This cipher takes alphanumerics into account
  # i.e. a total of 36 characters

  # take x and return x % len(key_string)
  SCREAMING_SNAKE_CASE					      =  numpy.vectorize(lambda lowerCAmelCase__   : x % 3_6   )

  SCREAMING_SNAKE_CASE					      =  numpy.vectorize(lowerCAmelCase__   )



  def __init__(self							,       _lowerCamelCase	):


        """simple docstring"""

        UpperCAmelCase__			:							str							=    self.modulus(_lowerCamelCase	)  # mod36 calc's on the encrypt key
        self.check_determinant()  # validate the determinant of the encryption key
        UpperCAmelCase__			:							List[str]							=    encrypt_key.shape[0]



  def  _a      (self							,       _lowerCamelCase	):


        """simple docstring"""

        return self.key_string.index(_lowerCamelCase	)



  def  _a      (self							,       _lowerCamelCase	):


        """simple docstring"""

        return self.key_string[round(_lowerCamelCase	)]



  def  _a      (self	):


        """simple docstring"""

        UpperCAmelCase__			:							List[Any]							=    round(numpy.linalg.det(self.encrypt_key	)	)

        if det < 0:
              UpperCAmelCase__			:							Dict							=    det % len(self.key_string	)

        UpperCAmelCase__			:							Dict							=    len(self.key_string	)
        if greatest_common_divisor(_lowerCamelCase							,       len(self.key_string	)	) != 1:
              UpperCAmelCase__			:							Optional[int]							=    (
                  F"""determinant modular {req_l} of encryption key({det}) """
                  F"""is not co prime w.r.t {req_l}.\nTry another key."""
              )
              raise ValueError(_lowerCamelCase	)



  def  _a      (self							,       _lowerCamelCase	):


        """simple docstring"""

        UpperCAmelCase__			:							Optional[int]							=    [char for char in text.upper() if char in self.key_string]

        UpperCAmelCase__			:							str							=    chars[-1]
        while len(_lowerCamelCase	) % self.break_key != 0:
              chars.append(_lowerCamelCase	)

        return "".join(_lowerCamelCase	)



  def  _a      (self							,       _lowerCamelCase	):


        """simple docstring"""

        UpperCAmelCase__			:							List[str]							=    self.process_text(text.upper()	)
        UpperCAmelCase__			:							Optional[Any]							=    """"""

        for i in range(0							,       len(_lowerCamelCase	) - self.break_key + 1							,       self.break_key	):
              UpperCAmelCase__			:							List[Any]							=    text[i : i + self.break_key]
              UpperCAmelCase__			:							Any							=    [self.replace_letters(_lowerCamelCase	) for char in batch]
              UpperCAmelCase__			:							Dict							=    numpy.array([vec]	).T
              UpperCAmelCase__			:							List[str]							=    self.modulus(self.encrypt_key.dot(_lowerCamelCase	)	).T.tolist()[
                  0
              ]
              UpperCAmelCase__			:							List[Any]							=    """""".join(
                  self.replace_digits(_lowerCamelCase	) for num in batch_encrypted	)
              encrypted += encrypted_batch

        return encrypted



  def  _a      (self	):


        """simple docstring"""

        UpperCAmelCase__			:							List[str]							=    round(numpy.linalg.det(self.encrypt_key	)	)

        if det < 0:
              UpperCAmelCase__			:							Dict							=    det % len(self.key_string	)
        UpperCAmelCase__			:							int							=    None
        for i in range(len(self.key_string	)	):
              if (det * i) % len(self.key_string	) == 1:
                    UpperCAmelCase__			:							Union[str, Any]							=    i
                    break

        UpperCAmelCase__			:							str							=    (
            det_inv
            * numpy.linalg.det(self.encrypt_key	)
            * numpy.linalg.inv(self.encrypt_key	)
        )

        return self.to_int(self.modulus(_lowerCamelCase	)	)




  def  _a      (self							,       _lowerCamelCase	):


        """simple docstring"""

        UpperCAmelCase__			:							Any							=    self.make_decrypt_key()
        UpperCAmelCase__			:							Optional[int]							=    self.process_text(text.upper()	)
        UpperCAmelCase__			:							Any							=    """"""

        for i in range(0							,       len(_lowerCamelCase	) - self.break_key + 1							,       self.break_key	):
              UpperCAmelCase__			:							Optional[Any]							=    text[i : i + self.break_key]
              UpperCAmelCase__			:							Optional[Any]							=    [self.replace_letters(_lowerCamelCase	) for char in batch]
              UpperCAmelCase__			:							Tuple							=    numpy.array([vec]	).T
              UpperCAmelCase__			:							Dict							=    self.modulus(decrypt_key.dot(_lowerCamelCase	)	).T.tolist()[0]
              UpperCAmelCase__			:							Optional[int]							=    """""".join(
                  self.replace_digits(_lowerCamelCase	) for num in batch_decrypted	)
              decrypted += decrypted_batch

        return decrypted




def 					a__						(						)	-> None:
      UpperCAmelCase__			:							List[Any]							=    int(input("""Enter the order of the encryption key: """    )    )
      UpperCAmelCase__			:							Optional[Any]							=    []

      print("""Enter each row of the encryption key with space separated integers"""    )
      for _ in range(lowerCAmelCase    ):
            UpperCAmelCase__			:							Union[str, Any]							=    [int(lowerCAmelCase    ) for x in input().split()]
            hill_matrix.append(lowerCAmelCase    )

      UpperCAmelCase__			:							Optional[Any]							=    HillCipher(numpy.array(lowerCAmelCase    )    )

      print("""Would you like to encrypt or decrypt some text? (1 or 2)"""    )
      UpperCAmelCase__			:							str							=    input("""\n1. Encrypt\n2. Decrypt\n"""    )
      if option == "1":
            UpperCAmelCase__			:							List[Any]							=    input("""What text would you like to encrypt?: """    )
            print("""Your encrypted text is:"""    )
            print(hc.encrypt(lowerCAmelCase    )    )
      elif option == "2":
            UpperCAmelCase__			:							Union[str, Any]							=    input("""What text would you like to decrypt?: """    )
            print("""Your decrypted text is:"""    )
            print(hc.decrypt(lowerCAmelCase    )    )


if __name__ == "__main__":
    import doctest

    doctest.testmod()

    main()




"""simple docstring"""
from typing import TYPE_CHECKING

from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_sentencepiece_available


_A							=  {}

try:
    if not is_sentencepiece_available():
        raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
    pass
else:
    _A							=  ["""BartphoTokenizer"""]

if TYPE_CHECKING:
    try:
        if not is_sentencepiece_available():
            raise OptionalDependencyNotAvailable()
    except OptionalDependencyNotAvailable:
        pass
    else:
        from .tokenization_bartpho import BartphoTokenizer

else:
    import sys

    _A							=  _LazyModule(__name__, globals()["""__file__"""], _import_structure, module_spec=__spec__)

