






import random
import sys

from . import cryptomath_module as cryptomath

lowerCAmelCase_     =			(
    R' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`'
    R'abcdefghijklmnopqrstuvwxyz{|}~'
)







def   snake_case		(				UpperCAmelCase						:							int,    UpperCAmelCase						:							int,    UpperCAmelCase						:							str ):
				if mode == "encrypt":
								if key_a == 1:
												sys.exit(
												    'The affine cipher becomes weak when key '
												    'A is set to 1. Choose different key' )
								if key_b == 0:
												sys.exit(
												    'The affine cipher becomes weak when key '
												    'B is set to 0. Choose different key' )
				if key_a < 0 or key_b < 0 or key_b > len(UpperCAmelCase ) - 1:
								sys.exit(
								    'Key A must be greater than 0 and key B must '
								    f'be between 0 and {len(UpperCAmelCase ) - 1}.' )
				if cryptomath.gcd(UpperCAmelCase,    len(UpperCAmelCase ) ) != 1:
								sys.exit(
								    f'Key A {key_a} and the symbol set size {len(UpperCAmelCase )} '
								    'are not relatively prime. Choose a different key.' )







def   snake_case		(				UpperCAmelCase						:							int,    UpperCAmelCase						:							str ):
				A			,		A									=   divmod(UpperCAmelCase,    len(UpperCAmelCase ) )
				check_keys(UpperCAmelCase,    UpperCAmelCase,    'encrypt' )
				A									=   ''
				for symbol in message:
								if symbol in SYMBOLS:
												A									=   SYMBOLS.find(UpperCAmelCase )
												cipher_text += SYMBOLS[(sym_index * key_a + key_b) % len(UpperCAmelCase )]
								else:
												cipher_text += symbol
				return cipher_text







def   snake_case		(				UpperCAmelCase						:							int,    UpperCAmelCase						:							str ):
				A			,		A									=   divmod(UpperCAmelCase,    len(UpperCAmelCase ) )
				check_keys(UpperCAmelCase,    UpperCAmelCase,    'decrypt' )
				A									=   ''
				A									=   cryptomath.find_mod_inverse(UpperCAmelCase,    len(UpperCAmelCase ) )
				for symbol in message:
								if symbol in SYMBOLS:
												A									=   SYMBOLS.find(UpperCAmelCase )
												plain_text += SYMBOLS[
												    (sym_index - key_b) * mod_inverse_of_key_a % len(UpperCAmelCase )
												]
								else:
												plain_text += symbol
				return plain_text







def   snake_case		(				):
				while True:
								A									=   random.randint(2,    len(UpperCAmelCase ) )
								A									=   random.randint(2,    len(UpperCAmelCase ) )
								if cryptomath.gcd(UpperCAmelCase,    len(UpperCAmelCase ) ) == 1 and key_b % len(UpperCAmelCase ) != 0:
												return key_b * len(UpperCAmelCase ) + key_b







def   snake_case		(				):
				A									=   input('Enter message: ' ).strip()
				A									=   int(input('Enter key [2000 - 9000]: ' ).strip() )
				A									=   input('Encrypt/Decrypt [E/D]: ' ).strip().lower()

				if mode.startswith('e' ):
								A									=   'encrypt'
								A									=   encrypt_message(UpperCAmelCase,    UpperCAmelCase )
				elif mode.startswith('d' ):
								A									=   'decrypt'
								A									=   decrypt_message(UpperCAmelCase,    UpperCAmelCase )
				print(f'\n{mode.title()}ed text: \n{translated}' )


if __name__ == "__main__":
					import doctest

					doctest.testmod()
					# main()













def   snake_case		(				UpperCAmelCase						:							set,    UpperCAmelCase						:							set ):
				assert isinstance(UpperCAmelCase,    UpperCAmelCase ), f'The input value of [set_a={set_a}] is not a set'
				assert isinstance(UpperCAmelCase,    UpperCAmelCase ), f'The input value of [set_b={set_b}] is not a set'

				return {a + b for a in set_a for b in set_b}


if __name__ == "__main__":
					from doctest import testmod

					testmod()





