




'''simple docstring'''




import string

import numpy





def      a_							(      __snake_case							:			int   ,       __snake_case							:			int   )							->						int:



       """simple docstring"""
       return b if a == 0 else greatest_common_divisor(b % a   ,       __snake_case   )


class   __UpperCamelCase       :
       lowercase	:    Optional[int]      						=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)
       lowercase	:    Any      						=numpy.vectorize(lambda lowerCamelCase__				: x % 36				)

       lowercase	:    List[str]      						=numpy.vectorize(lowerCamelCase__				)






       def __init__(							self,		lowerCAmelCase  ):



              """simple docstring"""







              lowerCamelCase_							=self.modulus(lowerCAmelCase  )  # mod36 calc's on the encrypt key
              self.check_determinant()  # validate the determinant of the encryption key
              lowerCamelCase_							=encrypt_key.shape[0]






       def      lowercase__     (							self,		lowerCAmelCase  ):



              """simple docstring"""







              return self.key_string.index(lowerCAmelCase  )






       def      lowercase__     (							self,		lowerCAmelCase  ):



              """simple docstring"""







              return self.key_string[round(lowerCAmelCase  )]






       def      lowercase__     (							self  ):



              """simple docstring"""







              lowerCamelCase_							=round(numpy.linalg.det(self.encrypt_key  )  )

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

              lowerCamelCase_							=len(self.key_string  )
              if greatest_common_divisor(lowerCAmelCase,		len(self.key_string  )  ) != 1:
                     lowerCamelCase_							=(
                         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      lowercase__     (							self,		lowerCAmelCase  ):



              """simple docstring"""







              lowerCamelCase_							=[char for char in text.upper() if char in self.key_string]

              lowerCamelCase_							=chars[-1]
              while len(lowerCAmelCase  ) % self.break_key != 0:
                     chars.append(lowerCAmelCase  )

              return "".join(lowerCAmelCase  )






       def      lowercase__     (							self,		lowerCAmelCase  ):



              """simple docstring"""







              lowerCamelCase_							=self.process_text(text.upper()  )
              lowerCamelCase_							=''''''

              for i in range(0,		len(lowerCAmelCase  ) - self.break_key + 1,		self.break_key  ):
                     lowerCamelCase_							=text[i : i + self.break_key]
                     lowerCamelCase_							=[self.replace_letters(lowerCAmelCase  ) for char in batch]
                     lowerCamelCase_							=numpy.array([vec]  ).T
                     lowerCamelCase_							=self.modulus(self.encrypt_key.dot(lowerCAmelCase  )  ).T.tolist()[
                         0
                     ]
                     lowerCamelCase_							=''''''.join(
                         self.replace_digits(lowerCAmelCase  ) for num in batch_encrypted  )
                     encrypted += encrypted_batch

              return encrypted






       def      lowercase__     (							self  ):



              """simple docstring"""







              lowerCamelCase_							=round(numpy.linalg.det(self.encrypt_key  )  )

              if det < 0:
                     lowerCamelCase_							=det % len(self.key_string  )
              lowerCamelCase_							=None
              for i in range(len(self.key_string  )  ):
                     if (det * i) % len(self.key_string  ) == 1:
                            lowerCamelCase_							=i
                            break

              lowerCamelCase_							=(
                  det_inv
                  * numpy.linalg.det(self.encrypt_key  )
                  * numpy.linalg.inv(self.encrypt_key  )
              )

              return self.to_int(self.modulus(lowerCAmelCase  )  )






       def      lowercase__     (							self,		lowerCAmelCase  ):



              """simple docstring"""







              lowerCamelCase_							=self.make_decrypt_key()
              lowerCamelCase_							=self.process_text(text.upper()  )
              lowerCamelCase_							=''''''

              for i in range(0,		len(lowerCAmelCase  ) - self.break_key + 1,		self.break_key  ):
                     lowerCamelCase_							=text[i : i + self.break_key]
                     lowerCamelCase_							=[self.replace_letters(lowerCAmelCase  ) for char in batch]
                     lowerCamelCase_							=numpy.array([vec]  ).T
                     lowerCamelCase_							=self.modulus(decrypt_key.dot(lowerCAmelCase  )  ).T.tolist()[0]
                     lowerCamelCase_							=''''''.join(
                         self.replace_digits(lowerCAmelCase  ) for num in batch_decrypted  )
                     decrypted += decrypted_batch

              return decrypted





def      a_							(      )							->						None:



       """simple docstring"""
       lowerCamelCase_							=int(input('''Enter the order of the encryption key: '''   )   )
       lowerCamelCase_							=[]

       print('''Enter each row of the encryption key with space separated integers'''   )
       for _ in range(__snake_case   ):
              lowerCamelCase_							=[int(__snake_case   ) for x in input().split()]
              hill_matrix.append(__snake_case   )

       lowerCamelCase_							=HillCipher(numpy.array(__snake_case   )   )

       print('''Would you like to encrypt or decrypt some text? (1 or 2)'''   )
       lowerCamelCase_							=input('''\n1. Encrypt\n2. Decrypt\n'''   )
       if option == "1":
              lowerCamelCase_							=input('''What text would you like to encrypt?: '''   )
              print('''Your encrypted text is:'''   )
              print(hc.encrypt(__snake_case   )   )
       elif option == "2":
              lowerCamelCase_							=input('''What text would you like to decrypt?: '''   )
              print('''Your decrypted text is:'''   )
              print(hc.decrypt(__snake_case   )   )


if __name__ == "__main__":
     import doctest

     doctest.testmod()

     main()









'''simple docstring'''




import string


def 				lowerCAmelCase_   (	_lowerCamelCase:   str					):
		__SCREAMING_SNAKE_CASE       :		Dict           =		""""""
		for i in sequence:
				__SCREAMING_SNAKE_CASE       :		Any           =		ord(_lowerCamelCase					)
				if 65 <= extract <= 90:
						output += chr(1_55 - extract					)
				elif 97 <= extract <= 1_22:
						output += chr(2_19 - extract					)
				else:
						output += i
		return output


def 				lowerCAmelCase_   (	_lowerCamelCase:   str					):
		__SCREAMING_SNAKE_CASE       :		Optional[Any]           =		string.ascii_letters
		__SCREAMING_SNAKE_CASE       :		Union[str, Any]           =		string.ascii_lowercase[::-1] + string.ascii_uppercase[::-1]
		return "".join(
		    letters_reversed[letters.index(_lowerCamelCase					)] if c in letters else c for c in sequence					)


def 				lowerCAmelCase_   (	):
		from timeit import timeit

		print("""Running performance benchmarks..."""					)
		__SCREAMING_SNAKE_CASE       :		Union[str, Any]           =		"""from string import printable ; from __main__ import atbash, atbash_slow"""
		print(F"> atbash_slow(): {timeit('atbash_slow(printable)'       ,      setup=_lowerCamelCase					)} seconds"					)
		print(F">      atbash(): {timeit('atbash(printable)'       ,      setup=_lowerCamelCase					)} seconds"					)


if __name__ == "__main__":
						for example in ("ABCDEFGH", "123GGjj", "testStringtest", "with space"):
												print(f"{example} encrypted in atbash: {atbash(example)}")
						benchmark()