예제 #1
0
def run_affine_cipher():
    """this method prompts the user if they would like to encrypt or decrypt
    and runs the encrypt or decrypt method of this cipher
    """
    affine = Affine()
    while True:
        encrypt_decrypt = input("\nEnter 1 to encrypt. Enter 2 to decrypt: ")
        if encrypt_decrypt == '1':
            affine.encrypt()
            break
        elif encrypt_decrypt == '2':
            affine.decrypt()
            break
        else:
            print("\nTry again! That is not a valid choice!")
예제 #2
0
class TestAffine(unittest.TestCase):
    def setUp(self):
        key = 2894
        self.message = '"A computer would deserve to be called intelligent if it could deceive a human into believing that it was human." -Alan Turing'
        self.encrypted_message = '"5QG9ol3La6QI93!xQxaia6faQL9QdaQG1!!axQARLa!!AuaRLQADQALQG93!xQxaGaAfaQ1QX3o1RQARL9Qda!AafARuQLX1LQALQI1iQX3o1RN"Q-5!1RQP36ARu'
        self.symbols = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 !?.'
        self.cipher = Affine(key, self.symbols)

    def test_encryption(self):
        self.assertEqual(self.cipher.encrypt(self.message),
                         self.encrypted_message)

    def test_decryption(self):
        self.assertEqual(self.cipher.decrypt(self.encrypted_message),
                         self.message)

    def test_weak_value_for_keyA_raises_error(self):
        key = 67
        self.assertRaisesRegex(ValueError, '^Key is weak when key A = 1$',
                               Affine, key, self.symbols)

    def test_weak_value_for_keyB_raises_error(self):
        key = 198
        self.assertRaisesRegex(ValueError, '^Key is weak when key B = 0$',
                               Affine, key, self.symbols)

    def test_coprime_keys_raises_error(self):
        key = 167
        self.assertRaisesRegex(
            ValueError,
            r'Multiplicative key \(2\) and length of symbols \(66\) must be co-prime',
            Affine, key, self.symbols)
예제 #3
0
def affine():
    """Prompts the user on operating a Affine Cipher."""

    answer = prompt()

    # Controls the choice of encrpytion or decryption
    if answer == 'E':
        word = input("Enter the word you want to encrpyt: ")
        test = Affine()
        output = test.encrypt(word)
        print("The encrpyted word is:  {} ".format(output))

        # Prompts the user on if they wish to decrpyt the word
        yes_no = input("Do you want to decrypt this word? [Y/N]: ").upper()
        if yes_no == 'Y':
            print("The decrypted word is: {} ".format(test.decrypt(output)))
    elif answer == 'D':
        word = input("Enter the word you want to decrpyt: ")
        test = Affine()
        output = test.decrypt(word)
        print("The decrpyted word is:  {} ".format(output))
    else:
        affine()

    # Asks if the user would like to use another cipher
    restart = input("Hit 'R' to restart program. Hit enter to quit").upper()
    if restart == 'R':
        start()
예제 #4
0
def app_menu():
    """Application menu"""
    enc_dec_choice = input(encrypt_decrypt_prompt).upper()
    if enc_dec_choice != encrypt and enc_dec_choice != decrypt:
        sys.exit()

    algorithm_choice = input(cipher_prompt).upper()

    if algorithm_choice == cipher_keyword:
        keyword_obj = KeywordCipher(input("PROVIDE KEYWORD\n"))
        if enc_dec_choice == encrypt:
            encryption_res = keyword_obj.encrypt(input(user_input_encrypt__prompt))
        else:
            decryption_result = keyword_obj.decrypt(input(user_input_decrypt__prompt))
    elif algorithm_choice == cipher_atbash:
        atbash_obj = Atbash()
        if enc_dec_choice == encrypt:
            encryption_res = atbash_obj.encrypt(input(user_input_encrypt__prompt))
        else:
            decryption_result = atbash_obj.decrypt(input(user_input_decrypt__prompt))
    elif algorithm_choice == cipher_affine:
        affine_obj = Affine()
        print("\nValid values for a factor: {0}".format(a_possible_values))
        a = check_a_factor(int(input(a_factor_prompt)))
        b = int(input(b_factor_prompt))
        if enc_dec_choice == encrypt:
            encryption_res = affine_obj.encrypt(input(user_input_encrypt__prompt), a, b)
        else:
            decryption_result = affine_obj.decrypt(input(user_input_decrypt__prompt), a, b)
    else:
        sys.exit()

    (print("ENCRYPTED STRING: {0}".format(encryption_res)) if enc_dec_choice == encrypt else
     print("DECRYPTED STRING: {0}".format(decryption_result)))
예제 #5
0
def test_affine_encrypt():
    plaintext = ciphertexts['plaintext']
    desired_ciphertext = ciphertexts['Affine']

    cipher = Affine(5, 8)
    encrypted_text = cipher.encrypt(plaintext)

    assert encrypted_text == desired_ciphertext
예제 #6
0
class CipherTests(unittest.TestCase):
    def setUp(self):
        self.test_word = 'testy'
        self.pad_word = 'loose'

        self.cipher = Cipher()
        self.affine = Affine(5, 9)
        self.atbash = Atbash()
        self.caesar = Caesar()
        self.keyword_cipher = Keyword(self.pad_word)

    def test_char_blocks(self):
        assert self.cipher.char_blocks('testytestytest') == 'testy testy test'
        assert self.cipher.char_blocks('exactlyten') == 'exact lyten'

    def test_use_pad(self):
        assert self.cipher.use_pad(self.test_word, self.pad_word) == 'ESGLC'

    def test_affine_encrypt(self):
        """Affine examples from http://crypto.interactive-maths.com/affine-cipher.html."""

        assert self.affine.encrypt(self.test_word) == 'ADVAZ'

    def test_affine_decrypt(self):
        """Affine examples from http://crypto.interactive-maths.com/affine-cipher.html."""

        assert self.affine.decrypt('ADVAZ') == self.test_word.upper()

    def test_atbash_encrypt(self):
        """Atbash examples from http://crypto.interactive-maths.com/atbash-cipher.html."""

        assert self.atbash.encrypt(self.test_word) == 'GVHGB'

    def test_atbash_decrypt(self):
        """Atbash examples from http://crypto.interactive-maths.com/atbash-cipher.html."""

        assert self.atbash.decrypt('GVHGB') == self.test_word.upper()

    def test_caesar_encrypt(self):
        """Caesar shifts by 3 every time.
        Caesar cipher examples from http://crypto.interactive-maths.com/caesar-cipher.html."""

        assert self.caesar.encrypt(self.test_word) == 'WHVWB'

    def test_caesar_decrypt(self):
        """Caesar shifts by 3 every time.
        Caesar cipher examples from http://crypto.interactive-maths.com/caesar-cipher.html."""

        assert self.caesar.decrypt('WHVWB') == self.test_word.upper()

    def test_keyword_encrypt(self):
        assert self.keyword_cipher.encrypt(self.test_word) == 'TARTY'

    def test_keyword_decrypt(self):
        assert self.keyword_cipher.decrypt('TARTY') == self.test_word.upper()
예제 #7
0
def secret():

    while True:
        cipher = ''
        print("\nBelow are the available ciphers. Please pick one.")
        ciphers = ['Affine', 'Atbash', 'Keyword']
        for cipher in ciphers:
            print("-{}".format(cipher))

        cipher_choice = input("\nWhich cipher would you like to use? ")
        clear_screen()
        if cipher_choice.lower() == 'affine':
            cipher = Affine()
        elif cipher_choice.lower() == 'atbash':
            cipher = Atbash()
        elif cipher_choice.lower() == 'keyword':
            keyword = input("What would you like your keyword to be? ")
            cipher = Keyword(keyword)
        elif cipher_choice.lower() == 'q':
            quit_program()
        else:
            print("I'm sorry. Please choose a cipher from the list.")
            secret()

        message = input("What would you like your message to be? ")

        choice = input("Would you like to encrypt or decrypt a message?")

        if choice.lower() == 'encrypt':
            cipher.encrypt(message)
        elif choice.lower() == 'decrypt':
            cipher.decrypt(message)
        elif choice.lower() == 'q':
            quit_program()
        elif choice.lower() != 'encrypt' or 'decrypt':
            print("Please choose either encryption or decryption.")
            secret()
예제 #8
0
def run_cipher(encrypt=True):
    """Sub menu with a list of implemented ciphers."""

    clear()
    prompt = "Choose a cipher to use:\n\n"
    prompt += "1) (Af)fine\n"
    prompt += "2) (At)bash\n"
    prompt += "3) (C)aesar\n"
    prompt += "4) (K)eyword\n\n"
    prompt += "Type (q) to quit.\n"


    user_input = input(prompt)

    affine_input = [1, '1', 'af']
    atbash_input = [2, '2', 'at']
    caesar_input = [3, '4', 'c']
    keyword_cipher_input = [4, '3', 'k']
    valid_input = affine_input + atbash_input + keyword_cipher_input + caesar_input

    if user_input.lower() == "q":
        return "q"

    while user_input not in valid_input:
        user_input = str(input(prompt))

    def ask_for_value():
        val_input = input("Enter value:\n")

        if not encrypt:
            val_input = Cipher.remove_char_blocks(val_input)

        return val_input

    text = ask_for_value()

    while text.lower().replace(" ", "").isalpha() is False:
        print("Value must contain letters only.\n")
        text = ask_for_value()

    # Affine inputs
    if user_input in affine_input:
        aff_first_number = input("Please enter a beginning number for the Affine cipher (must be odd):\n")
        aff_second_number = input("Please enter an ending number for the Affine cipher:\n")

        while aff_first_number.isnumeric() is False \
                or int(aff_first_number) % 2 == 0 \
                or aff_second_number.isnumeric() is False:
            print("Value must contain numbers. First number must be odd.\n")
            aff_first_number = input("Please enter a beginning number for the Affine Cipher (must be odd):\n")
            aff_second_number = input("Please enter an ending number for the Affine cipher:\n")

        cipher = Affine(aff_first_number, aff_second_number)

    # Atbash inputs
    if user_input in atbash_input:
        cipher = Atbash()

    # Keyword inputs
    if user_input in keyword_cipher_input:
        user_keyword = input("Please enter your keyword for the Keyword Cipher:\n")

        while text.lower().isalpha() is False:
            print("Value must contain letters only.\n")
            user_keyword = input("Please enter keyword for the Keyword Cipher:\n")

        cipher = Keyword(user_keyword)

    if user_input in caesar_input:
        cipher = Caesar()

    if encrypt:
        text = cipher.encrypt(text)
        if input("Do you want to add a secret pad? (Y/n)\n").lower() == "y":
            text = pad_option(text, cipher)

        val = cipher.char_blocks(text)
    else:
        if input("Was a secret pad used? (Y/n)\n").lower() == "y":
            text = pad_option(text, cipher, encrypt=False)

        val = cipher.decrypt(text)

    return val
예제 #9
0
def encrypt_decrypt():
    """Encrypt or decrypt text."""

    playing = True

    while playing:
        #User input
        cipher = int(
            input("Enter the number associated with cipher you wish to use: "))
        text = input("What is the message?: ")
        choice = input(
            "Are you going to encrypt or decrypt? Enter E or D: ").lower()
        print("\n")

        if choice == "e":
            #Generates affine cipher
            if cipher == 1:
                affine = Affine()
                print(affine.encrypt(text))
                playing = False

            #Generates atbash cipher
            elif cipher == 2:
                atbash = Atbash()
                print(atbash.encrypt(text))
                playing = False

            #Generates keyword cipher
            elif cipher == 3:
                #Ask user keyword
                secret_key = input("Enter your keyword: ")
                keyword = Keyword()
                print("\n")
                print(keyword.encrypt(text, secret_key))
                playing = False

        if choice == "d":
            #Decrypts affine cipher
            if cipher == 1:
                affine = Affine()
                print(affine.decrypt(text))
                playing = False

            #Decrypts atbash cipher
            elif cipher == 2:
                atbash = Atbash()
                print(atbash.decrypt(text))
                playing = False

            #Decrypts keyword cipher
            elif cipher == 3:
                secret_key = input("Enter your keyword: ")
                keyword = Keyword()
                print("\n")
                print(keyword.decrypt(text, secret_key))
                playing = False

    #Asks user to play again or not
    else:
        if input("\nDo you want to contine? Y/N: ").lower() == "y":
            welcome()
            encrypt_decrypt()
        else:
            print("See you next time!")
예제 #10
0
def run_cipher(encrypt=True):
    """Sub menu with a list of implemented ciphers."""
    global key_val     
    clear()
    prompt = "Choose a cipher to use:\n\n"
    prompt += "1) (Af)fine\n"
    prompt += "2) (At)bash\n"
    prompt += "3) (K)eyword\n\n"
    prompt += "Type (q) to quit.\n"


    user_input = input(prompt)

    affine_input = [1, '1', 'af']
    atbash_input = [2, '2', 'at']
    keyword_cipher_input = [3, '3', 'k']
    valid_input = affine_input + atbash_input + keyword_cipher_input

    if user_input.lower() == "q":
        return "q"

    while user_input not in valid_input:
        user_input = str(input(prompt))

    def ask_for_message():
        val_input = input("Enter message:\n")

        return val_input

    text = ask_for_message()

    while text.lower().isalpha() is False:
        print("Message must contain letters only.\n")
        text = ask_for_message()

    # Affine inputs
    if user_input in affine_input:
        aff_first_number = input("Please enter a beginning number for the Affine cipher (must be odd):\n")
        aff_second_number = input("Please enter an ending number for the Affine cipher:\n")

        while aff_first_number.isnumeric() is False \
                or int(aff_first_number) % 2 == 0 \
                or aff_second_number.isnumeric() is False:
            print("Value must contain numbers. First number must be odd.\n")
            aff_first_number = input("Please enter a beginning number for the Affine Cipher (must be odd):\n")
            aff_second_number = input("Please enter an ending number for the Affine cipher:\n")

        cipher = Affine(aff_first_number, aff_second_number)

    # Atbash inputs
    if user_input in atbash_input:
        cipher = Atbash()

    # Keyword inputs   
    if user_input in keyword_cipher_input:
        user_keyword = input("Please enter your keyword for the Keyword Cipher:\n")

        while text.lower().isalpha() is False:
            print("Message must contain letters only.\n")
            user_keyword = input("Please enter keyword for the Keyword Cipher:\n")

        cipher = Keyword(user_keyword)
    
    if encrypt:
        key_val = cipher.encrypt(text)

    else:
        key_val = cipher.decrypt(text)

    
    return key_val
def cipher_selection():
    """The first screen shows all the cipher options to encrypt and decrypt."""
    selection_ed = (input("To encrypt a message, press E.\n"
                          "To decrypt a message, press D.\n"
                          "To quit, press Q.\n")).upper()
    if selection_ed == 'E':
        cipher_option = (input("Please select one of these cipher options:\n"
                               "Affine: Press AFE\n"
                               "Atbash: Press ABE\n"
                               "Polybius: Press POE\n"
                               "To quit, press Q.\n")).upper()
        if cipher_option == "AFE":
            a = int(
                input(
                    'Enter an alpha. Available values: 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25\n'
                ))
            if a not in [3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25]:
                print('Alpha value is not accepted. Please try again.\n')
                a = int(
                    input(
                        'Enter an alpha. Available values: 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25\n'
                    ))
            b = int(input('Enter a beta value. Integer numbers only.\n'))
            text = (input('What is your message?\n')).upper()
            x = Affine(a, b)
            x.encrypt(text)
            menu_back()
        if cipher_option == 'ABE':
            text = (input('What is your message?\n')).upper()
            x = Atbash()
            x.encrypt(text)
            menu_back()
        if cipher_option == 'POE':
            text = (input('What is your message?\n')).upper()
            x = Polybius()
            x.encrypt(text)
            menu_back()
        if cipher_option == 'Q':
            print('You quit.\n')
            os.system('clear')
        else:
            print('Not valid. Please try again.')
            menu_back()

    if selection_ed == 'D':
        cipher_option = (input("Please select one of these cipher options:\n"
                               "Affine: Press AFD\n"
                               "Atbash: Press ABD\n"
                               "Polybius: Press POD\n"
                               "To quit, enter Q.\n")).upper()
        if cipher_option == "AFD":
            a = int(
                input(
                    'Enter an alpha. Available values: 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25\n'
                ))
            b = int(input('Enter a beta value.\n'))
            text = (input('What is your message?\n')).upper()
            x = Affine(a, b)
            x.decrypt(text)
            menu_back()
        if cipher_option == 'ABD':
            text = (input('What is your message?\n')).upper()
            x = Atbash()
            x.decrypt(text)
            menu_back()
        if cipher_option == 'POD':
            text = (input('What is your message?\n')).upper()
            x = Polybius()
            x.decrypt(text)
            menu_back()
        else:
            print('Not valid. Please try again.\n')
            menu_back()
    if selection_ed == 'Q':
        print('You quit.\n')
        os.system('clear')
    else:
        print('Not valid.\n')
        menu_back()
def __affine_cipher(encrypt_or_decrypt, working_text):
    '''
    Function contains logic that allows user to specify values
    for the mathematical function implemented in the affine cipher,
    or simply use the predefined values.
    '''
    if encrypt_or_decrypt == "encryption":
        __clear()

        # Asking to specify A and B values.
        affine_option = input(
            "Would you like to specify values for the Affine Function? [y/N] "
        ).upper()
        if affine_option == 'Y':
            __clear()
            print('!BE SURE TO WRITE DOWN THE VALUES YOU USE!\n')
            # Declaring B Value
            b_val = int(
                input(
                    'Specify an integer value "b" that is between 1 and 93: '))
            if b_val <= 1 or b_val >= 93:
                print('The "b" value must 1 <= b <= 93')
                __affine_cipher(encrypt_or_decrypt, working_text)

            # Declaring A Value
            a_val = int(
                input(
                    'Specify an integer value "a" that must be 1 <= a <= 93 & the greatest common divisor for "a" and 93 should be one: '
                ))
            if a_val >= 1 and a_val <= 93 and gcd(a_val, 93) == 1:

                # Encrypting using affine and returning text
                affine_encryption = Affine(working_text, a_val, b_val)
                return affine_encryption.encrypt()
            else:
                # User input error
                __clear()
                input(
                    'The "a" value must be 1 <= a <= 93 & the greatest common divisor for "a" and 93 should be one.'
                )
                __affine_cipher(encrypt_or_decrypt, working_text)

        elif affine_option == "N":
            # Using Predefined A and B values for affine encryption.
            affine_encryption = Affine(working_text)
            return affine_encryption.encrypt()

        else:
            # Whoops user mistyped
            __clear()
            input(
                'The option specified by the user was not recognized. \nPlease try again'
            )
            __affine_cipher(encrypt_or_decrypt, working_text)

    elif encrypt_or_decrypt == "decryption":
        __clear()

        # Asking if user provided their nums for affine function.
        affine_question = input(
            "Did you specify your own values for the Affine cipher's mathematical function? [y/N] "
        ).upper()

        # Grabbing user defined values for a and b.
        if affine_question == 'Y':
            __clear()
            b_val = int(input("Please enter the value you used for 'b': "))
            a_val = int(input("Please enter the value you used for 'a': "))
            affine_decryption = Affine(working_text, a_val, b_val)
            return affine_decryption.decrypt()

        # Use standard values for affine function.
        elif affine_question == "N":
            __clear()
            affine_decryption = Affine(working_text)
            return affine_decryption.decrypt()
        else:
            # Whoops user mistyped
            input(
                'The option specified by the user was not recognized. \nPlease try again'
            )
            __affine_cipher(encrypt_or_decrypt, working_text)
예제 #13
0
def play():
    """
    Asks the user what cipher he wants to use,
    in order to encrypt or decrypt a text message.
    Gives user the option to return the cipher text in 5 characters blocks.
    Asks user for different input based on cipher selection.
    Adds a onetime pad as an additional security layer.
    If encrypting:
    Returns cipher text encrypted with the chosen cipher and onetime pad.
    If decrypting:
    Returns text decrypted with the chosen cipher and onetime pad.
    """
    working = True
    cipher_choice = True
    enc_dec = True
    letters = string.ascii_uppercase
    while working:
        clear_screen()
        print(
            "This is the Secret Messages project for the Treehouse Techdegree. \n"
            "These are the current available ciphers: \n"
            "- Affine \n"
            "- Atbash \n"
            "- Caesar \n"
            "- Keyword \n"
            "- Type (Q) to quit. \n")
        while cipher_choice:
            choice = input(
                "Type the name of the cipher would you like to use? \n")
            if choice.upper() == 'Q':
                exit()
            elif choice.upper() == 'AFFINE':
                cipher = Affine()
                break
            elif choice.upper() == 'ATBASH':
                cipher = Atbash()
                break
            elif choice.upper() == 'CAESAR':
                cipher = Caesar()
                break
            elif choice.upper() == 'KEYWORD':
                cipher = Keyword()
                break
            else:
                print('Type the name of any available cipher. \n')

        user_text = input('What is your message?(Letters only) \n')

        while enc_dec:
            e_or_d = input('Are we going to encrypt or decrypt? \n')
            if e_or_d.upper() == 'ENCRYPT' and isinstance(cipher, Affine):
                alpha, beta = get_keys()
                ot_pad = input('Type your one time pad. \n')
                ot_val = cipher.one_time_pad(user_text, ot_pad)
                value = cipher.encrypt(ot_val, alpha, beta)
                block_choice = yes_or_no()
                if block_choice.upper() == 'Y':
                    value = cipher.add_padding(value)
                    print(value + '\n')
                    repeat()
                    break
                else:
                    print(value + '\n')
                    repeat()
                    break
            elif e_or_d.upper() == 'DECRYPT' and isinstance(cipher, Affine):
                alpha, beta = get_keys()
                ot_pad = input(
                    'Type your one time pad, must be the same used for encrypting. \n'
                )
                block_choice = y_o_n()
                if block_choice.upper() == 'Y':
                    no_block = cipher.remove_padding(user_text)
                    value = cipher.decrypt(no_block, alpha, beta)
                    ot_val = cipher.one_time_pad(value, ot_pad, encrypt=False)
                    print(ot_val + '\n')
                    repeat()
                    break
                else:
                    value = cipher.decrypt(user_text, alpha, beta)
                    ot_val = cipher.one_time_pad(value, ot_pad, encrypt=False)
                    print(ot_val + '\n')
                    repeat()
                    break
            elif e_or_d.upper() == 'ENCRYPT' and isinstance(cipher, Atbash):
                ot_pad = input('Type your one time pad. \n')
                ot_val = cipher.one_time_pad(user_text, ot_pad)
                value = cipher.encrypt(ot_val)
                block_choice = yes_or_no()
                if block_choice.upper() == 'Y':
                    value = cipher.add_padding(value)
                    print(value + '\n')
                    repeat()
                    break
                else:
                    print(value + '\n')
                    repeat()
                    break
            elif e_or_d.upper() == 'DECRYPT' and isinstance(cipher, Atbash):
                ot_pad = input(
                    'Type your one time pad, must be the same used for encrypting. \n'
                )
                block_choice = y_o_n()
                if block_choice.upper() == 'Y':
                    no_block = cipher.remove_padding(user_text)
                    value = cipher.decrypt(no_block)
                    ot_val = cipher.one_time_pad(value, ot_pad, encrypt=False)
                    print(ot_val + '\n')
                    repeat()
                    break
                else:
                    value = cipher.decrypt(user_text)
                    ot_val = cipher.one_time_pad(value, ot_pad, encrypt=False)
                    print(ot_val + '\n')
                    repeat()
                    break
            elif e_or_d.upper() == 'ENCRYPT' and isinstance(cipher, Caesar):
                ot_pad = input('Type your one time pad. \n')
                ot_val = cipher.one_time_pad(user_text, ot_pad)
                value = cipher.encrypt(ot_val)
                block_choice = yes_or_no()
                if block_choice.upper() == 'Y':
                    value = cipher.add_padding(value)
                    print(value + '\n')
                    repeat()
                    break
                else:
                    print(value + '\n')
                    repeat()
                    break
            elif e_or_d.upper() == 'DECRYPT' and isinstance(cipher, Caesar):
                ot_pad = input(
                    'Type your one time pad, must be the same used for encrypting. \n'
                )
                block_choice = y_o_n()
                if block_choice.upper() == 'Y':
                    no_block = cipher.remove_padding(user_text)
                    value = cipher.decrypt(no_block)
                    ot_val = cipher.one_time_pad(value, ot_pad, encrypt=False)
                    print(ot_val + '\n')
                    repeat()
                    break
                else:
                    value = cipher.decrypt(user_text)
                    ot_val = cipher.one_time_pad(value, ot_pad, encrypt=False)
                    print(ot_val + '\n')
                    repeat()
                    break
            elif e_or_d.upper() == 'ENCRYPT' and isinstance(cipher, Keyword):
                ot_pad = input('Type your one time pad. \n')
                keyword_choice = get_keyword()
                ot_val = cipher.one_time_pad(user_text, ot_pad)
                value = cipher.encrypt(ot_val, keyword_choice)
                block_choice = yes_or_no()
                if block_choice.upper() == 'Y':
                    value = cipher.add_padding(value)
                    print(value + '\n')
                    repeat()
                    break
                else:
                    print(value + '\n')
                    repeat()
                    break
            elif e_or_d.upper() == 'DECRYPT' and isinstance(cipher, Keyword):
                ot_pad = input(
                    'Type your one time pad, must be the same used for encrypting. \n'
                )
                block_choice = y_o_n()
                keyword_choice = get_keyword()
                if block_choice.upper() == 'Y':
                    no_block = cipher.remove_padding(user_text)
                    value = cipher.decrypt(no_block, keyword_choice)
                    ot_val = cipher.one_time_pad(value, ot_pad, encrypt=False)
                    print(ot_val + '\n')
                    repeat()
                    break
                else:
                    value = cipher.decrypt(user_text, keyword_choice)
                    ot_val = cipher.one_time_pad(value, ot_pad, encrypt=False)
                    print(ot_val + '\n')
                    repeat()
                    break
    def run_cipher():
        print(
            "This is the Secret Message project for the Treehouse Techdegree. \n"
        )
        user_choice = input(
            "Would you like to encrypt or decrypt a message? \n \n")

        if user_choice.lower() == "encrypt":
            text = input("What message would you like to encrypt? \n \n")
            cipher_type = input(
                "Which cipher would you like to use to encrypt? \n"
                "\n - Keyword"
                "\n - Atbash"
                "\n - Affine"
                "\n - Caesar \n"
                "\n")

            #Keyword Cipher
            if cipher_type.lower() == "keyword":
                secret_keyword = input(
                    "Great Choice! What is your keyword? \n \n")
                keyword = Keyword()
                print('\n')
                print(keyword.encrypt(text, secret_keyword))

            #Atbash Cipher
            elif cipher_type.lower() == "atbash":
                atbash = Atbash()
                print('\n')
                print(atbash.encrypt(text))

            #Affine Cipher
            elif cipher_type.lower() == "affine":
                affine = Affine()
                print('\n')
                print(affine.encrypt(text))

            #Caesar Cipher
            elif cipher_type.lower() == "caesar":
                caesar = Caesar()
                print('\n')
                print(caesar.encrypt(text))

            elif ValueError:
                print(" \nSorry, {} is not a choice!".format(cipher_type))
                run_cipher()

        elif user_choice.lower() == "decrypt":
            text = input("What message would you like to decrypt? \n \n")
            cipher_type = input(
                "Which cipher would you like to use to decrypt? \n"
                "\n - Keyword"
                "\n - Atbash"
                "\n - Affine"
                "\n - Caesar \n"
                "\n")

            #Keyword Cipher
            if cipher_type.lower() == "keyword":
                secret_keyword = input(
                    "Great Choice! What is your keyword? \n \n")
                keyword = Keyword()
                print('\n')
                print(keyword.decrypt(text, secret_keyword))

            #Atbash Cipher
            elif cipher_type.lower() == "atbash":
                atbash = Atbash()
                print(atbash.decrypt(text))

            #Affine Cipher
            elif cipher_type.lower() == "affine":
                affine = Affine()
                print('\n')
                print(affine.decrypt(text))

            #Caesar Cipher
            elif cipher_type.lower() == "caesar":
                caesar = Caesar()
                print('\n')
                print(caesar.decrypt(text))

            #If the cipher type is not a choice
            elif ValueError:
                print(" \nSorry, {} is not a choice!".format(cipher_type))
                run_cipher()

        elif ValueError:
            print("{} wasn't an option. \n".format(user_choice))
            run_cipher()