Advertisement
Python253

cipher_tool_101

May 7th, 2024 (edited)
2,492
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.28 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Filename: cipher_tool_101.py
  4. # Version: 1.0.1
  5. # Author: Jeoi Reqi
  6.  
  7. """
  8. This script serves as a comprehensive tool for encoding and decoding various classical ciphers as well as Fernet encryption and decryption.
  9.  
  10. It offers functionalities for a range of encoding and decoding techniques for the following:
  11.  
  12.    1: Caesar Cipher:
  13.        - Allows encoding and decoding text by shifting characters a fixed number of positions in the alphabet.
  14.  
  15.    2: A1Z26 Cipher:
  16.        - For encoding, it converts alphabetic characters into their corresponding numeric positions in the alphabet.
  17.        - During decoding, it reverses this process, converting numeric sequences back into alphabetic characters.
  18.            - Note: Spaces in the encoded text are represented by '0'.
  19.  
  20.    3: Atbash Cipher:
  21.        - Inverts the alphabet, substituting each letter with its reverse counterpart.
  22.  
  23.    4: Rail Fence Cipher:
  24.        - Utilizes a transposition technique, encoding text by writing it in a zigzag pattern across a specified number of "rails".
  25.          Then it reads off the encoded text row by row to decode to plaintext.
  26.  
  27.    5: Vigenère Cipher:
  28.        - Employs a keyword to encode text, shifting characters in a repeating pattern based on the keyword's letters.
  29.        - Decoding with Vigenère reverses this process, decrypting text based on the keyword.
  30.  
  31.    6: Fernet Encryption/Decryption:
  32.        - Encrypts the input text using the Fernet symmetric encryption algorithm.
  33.        - Decrypts the input text using the same Fernet key used for encryption.
  34.  
  35. Requirements:
  36.    - Python 3.x
  37.    - Colorama (install with 'pip install colorama')
  38.    - cryptography library (install with 'pip install cryptography')
  39.    
  40. Usage:
  41.    - Run the script and choose a cipher type by entering the corresponding number.
  42.    - Follow the prompts to enter the text and any required parameters.
  43.    - The script will output the encoded or decoded text.
  44.  
  45. Additional Notes:
  46.    - For Rail Fence cipher, the number of rails must be a positive integer.
  47.    - For Vigenère cipher, the key should be a string of alphabetic characters.
  48.    - For A1Z26 cipher:
  49.        - When encoding, the input text should consist of alphabetic characters.
  50.        - When decoding, the input text should consist of numeric characters separated by spaces.
  51. """
  52.  
  53. # IMPORTS
  54. from colorama import Fore, Style
  55. from cryptography.fernet import Fernet
  56. import os
  57.  
  58. # CAESAR CIPHER
  59. def caesar_cipher(text, shift, mode):
  60.     """
  61.    Caesar cipher encoding or decoding.
  62.  
  63.    Args:
  64.        text (str): The text to be encoded or decoded.
  65.        shift (int): The shift value for encoding or decoding.
  66.        mode (str): '1' for encoding, '2' for decoding.
  67.  
  68.    Returns:
  69.        str: The encoded or decoded text.
  70.    """
  71.     result = ""
  72.     for char in text:
  73.         if char.isalpha():
  74.             if mode == '1':  # Encode
  75.                 if char.islower():
  76.                     result += chr((ord(char) - 97 + shift) % 26 + 97)
  77.                 else:
  78.                     result += chr((ord(char) - 65 + shift) % 26 + 65)
  79.             elif mode == '2':  # Decode
  80.                 if char.islower():
  81.                     result += chr((ord(char) - 97 - shift) % 26 + 97)
  82.                 else:
  83.                     result += chr((ord(char) - 65 - shift) % 26 + 65)
  84.         else:
  85.             result += char
  86.     return result
  87.  
  88. # A1Z26 CIPHER
  89. def a1z26_cipher(text, mode):
  90.     """
  91.    A1Z26 cipher encoding or decoding.
  92.  
  93.    Args:
  94.        text (str): The text to be encoded or decoded.
  95.        mode (str): '3' for encoding, '4' for decoding.
  96.  
  97.    Returns:
  98.        str: The encoded or decoded text.
  99.    """
  100.     if mode == '3':    # ENCODE
  101.         result = ' '.join(str(ord(char) - 96) if char.isalpha() else '0' for char in text)
  102.     elif mode == '4':  # DECODE
  103.         result = ''
  104.         nums = text.split()
  105.         for num in nums:
  106.             if num == '0':
  107.                 result += ' '
  108.             else:
  109.                 result += chr(int(num) + 96)
  110.     else:
  111.         result = "\nInvalid mode! Please choose '3' for encoding or '4' for decoding.\n"
  112.     return result
  113.  
  114. # ATBASH CIPHER
  115. def atbash_cipher(text, mode):
  116.     """
  117.    Atbash cipher encoding or decoding.
  118.  
  119.    Args:
  120.        text (str): The text to be encoded or decoded.
  121.        mode (str): '5' for encoding, '6' for decoding.
  122.  
  123.    Returns:
  124.        str: The encoded or decoded text.
  125.    """
  126.     result = ""
  127.     for char in text:
  128.         if char.isalpha():
  129.             if char.islower():
  130.                 result += chr(122 - ord(char) + 97)
  131.             else:
  132.                 result += chr(90 - ord(char) + 65)
  133.         else:
  134.             result += char
  135.     return result
  136.  
  137. # RAILFENCE CIPHER
  138. def encode_RailFence(text, key):
  139.     """
  140.    Rail Fence cipher encoding.
  141.  
  142.    Args:
  143.        text (str): The text to be encoded.
  144.        key (int): The number of rails.
  145.  
  146.    Returns:
  147.        str: The encoded text.
  148.    """
  149.     rail = [['\n' for i in range(len(text))] for j in range(key)]
  150.     dir_down = False
  151.     row, col = 0, 0
  152.      
  153.     for i in range(len(text)):
  154.         if (row == 0) or (row == key - 1):
  155.             dir_down = not dir_down
  156.          
  157.         rail[row][col] = text[i]
  158.         col += 1
  159.          
  160.         if dir_down:
  161.             row += 1
  162.         else:
  163.             row -= 1
  164.    
  165.     result = []
  166.     for i in range(key):
  167.         for j in range(len(text)):
  168.             if rail[i][j] != '\n':
  169.                 result.append(rail[i][j])
  170.     return ''.join(result)
  171.  
  172. # VIGENERE CIPHER
  173. def vigenere_cipher(text, key, mode):
  174.     """
  175.    Vigenère cipher encoding or decoding.
  176.  
  177.    Args:
  178.        text (str): The text to be encoded or decoded.
  179.        key (str): The key for encoding or decoding.
  180.        mode (str): '9' for encoding, '10' for decoding.
  181.  
  182.    Returns:
  183.        str: The encoded or decoded text.
  184.    """
  185.     result = ""
  186.     key_length = len(key)
  187.     key_index = 0
  188.     for char in text:
  189.         if char.isalpha():
  190.             if mode == '9':  # Encode
  191.                 if char.islower():
  192.                     shift = ord(key[key_index].lower()) - 97
  193.                     result += chr((ord(char) - 97 + shift) % 26 + 97)
  194.                 else:
  195.                     shift = ord(key[key_index].lower()) - 97
  196.                     result += chr((ord(char) - 65 + shift) % 26 + 65)
  197.             elif mode == '10':  # Decode
  198.                 if char.islower():
  199.                     shift = ord(key[key_index].lower()) - 97
  200.                     result += chr((ord(char) - 97 - shift) % 26 + 97)
  201.                 else:
  202.                     shift = ord(key[key_index].lower()) - 97
  203.                     result += chr((ord(char) - 65 - shift) % 26 + 65)
  204.             key_index = (key_index + 1) % key_length
  205.         else:
  206.             result += char
  207.     return result
  208.  
  209. # GENERATE KEY
  210. def generate_key():
  211.     """
  212.    Generate a new Fernet key and save it to a file.
  213.  
  214.    Returns:
  215.        bytes: The generated Fernet key.
  216.    """
  217.     key = Fernet.generate_key()
  218.     with open("key.txt", "wb") as key_file:
  219.         key_file.write(key)
  220.     return key
  221.  
  222. # LOAD STORED KEY FROM FILE
  223. def load_key():
  224.     """
  225.    Load the Fernet key from the key file if it exists.
  226.  
  227.    Returns:
  228.        bytes: The loaded Fernet key if exists, otherwise None.
  229.    """
  230.     if os.path.exists("key.txt"):
  231.         with open("key.txt", "rb") as key_file:
  232.             return key_file.read()
  233.     else:
  234.         print("\nNo saved key found!\n\n- Generating a new 32-byte Fernet key...\n")
  235.         return generate_key()
  236.  
  237. # DELETE STORED KEY
  238. def delete_key():
  239.     """
  240.    Delete the key file if it exists.
  241.    """
  242.     if os.path.exists("key.txt"):
  243.         os.remove("key.txt")
  244.         print("\nKey deleted!")
  245.     else:
  246.         print("\nNo key to delete!")
  247.  
  248. def fernet_encode():
  249.     """
  250.    Encode the input text using the Fernet symmetric encryption algorithm.
  251.    """
  252.     while True:
  253.         print("\nChoose an option:")
  254.         print("1. Generate Key")
  255.         print("2. Delete Key")
  256.         print("3. Use Stored Key")
  257.  
  258.         key_choice = input("\nEnter your choice: ")
  259.        
  260.         if key_choice == '1':  # Generate Key
  261.             key = generate_key()
  262.             print("\nGenerated new key:\n", key.decode())
  263.             text = input("\nEnter the text to encode using Fernet: ")
  264.             print("Encoding with the generated key...")
  265.             cipher_suite = Fernet(key)
  266.             encoded_text = cipher_suite.encrypt(text.encode())
  267.             print("\nEncoded text:\n", encoded_text.decode())
  268.             break  # Exit the loop after encoding
  269.         elif key_choice == '2':  # Delete Key
  270.             delete_key()
  271.         elif key_choice == '3':  # Use Stored Key
  272.             key = load_key()
  273.             if key is not None:
  274.                 print("Encoding with the stored key:\n", key.decode())
  275.                 text = input("\nEnter the text to encode using Fernet: ")
  276.                 cipher_suite = Fernet(key)
  277.                 encoded_text = cipher_suite.encrypt(text.encode())
  278.                 print("\nEncoded text:\n", encoded_text.decode())
  279.                 break  # Exit the loop after encoding
  280.             else:
  281.                 print("\nNo key found! Please generate or load a key.")
  282.         else:
  283.             print("\nInvalid choice! Please enter 1, 2, or 3.")
  284.  
  285. def fernet_decode():
  286.     """
  287.    Decode the input text using the Fernet symmetric encryption algorithm.
  288.  
  289.    Returns:
  290.        str: The decoded text.
  291.    """
  292.     while True:
  293.         print("\nChoose an option:")
  294.         print("1. Input Key Manually")
  295.         print("2. Use Stored Key")
  296.  
  297.         key_choice = input("\nEnter your choice: ")
  298.        
  299.         if key_choice == '1':  # Input Key Manually
  300.             key = input("\nEnter the Fernet key: ").encode()
  301.             cipher_suite = Fernet(key)
  302.             encoded_text = input("\nEnter the text to decode using Fernet: ")
  303.             decoded_text = cipher_suite.decrypt(encoded_text.encode()).decode()
  304.             print("\nDecoded text:\n", decoded_text)
  305.             break  # Exit the loop after decoding
  306.         elif key_choice == '2':  # Use Stored Key
  307.             key = load_key()
  308.             if key is not None:
  309.                 encoded_text = input("\nEnter the text to decode using Fernet: ")
  310.                 cipher_suite = Fernet(key)
  311.                 decoded_text = cipher_suite.decrypt(encoded_text.encode()).decode()
  312.                 print("\nDecoded text:\n", decoded_text)
  313.                 break  # Exit the loop after decoding
  314.             else:
  315.                 print("\nNo key found! Please generate or load a key.")
  316.         else:
  317.             print("\nInvalid choice! Please enter 1 or 2.")
  318.  
  319. # MAIN MENU & FUNCTION CALLS
  320. def main():
  321.     """
  322.    Main function to run the cipher tool.
  323.    """
  324.     while True:
  325.         print("-" * 28)
  326.         print(Style.BRIGHT + Fore.GREEN + "     :: CIPHER TOOL ::" + Style.RESET_ALL)
  327.         print("-" * 28)
  328.         print(Style.BRIGHT +"\nCHOOSE A CIPHER TYPE:\n" + Style.RESET_ALL)
  329.         print(Style.BRIGHT + "01. " + Fore.GREEN + "Caesar Encode        [+]" + Style.RESET_ALL)
  330.         print(Style.BRIGHT + "02. " + Fore.YELLOW + "Caesar Decode        [-]" + Style.RESET_ALL)
  331.         print(Style.BRIGHT + "03. " + Fore.GREEN + "A1Z26 Encode         [+]" + Style.RESET_ALL)
  332.         print(Style.BRIGHT + "04. " + Fore.YELLOW + "A1Z26 Decode         [-]" + Style.RESET_ALL)
  333.         print(Style.BRIGHT + "05. " + Fore.GREEN + "Atbash Encode        [+]" + Style.RESET_ALL)
  334.         print(Style.BRIGHT + "06. " + Fore.YELLOW + "Atbash Decode        [-]" + Style.RESET_ALL)
  335.         print(Style.BRIGHT + "07. " + Fore.GREEN + "Rail Fence Encode    [+]" + Style.RESET_ALL)
  336.         print(Style.BRIGHT + "08. " + Fore.YELLOW + "Rail Fence Decode    [-]" + Style.RESET_ALL)
  337.         print(Style.BRIGHT + "09. " + Fore.GREEN + "Vigenère Encode      [+]" + Style.RESET_ALL)
  338.         print(Style.BRIGHT + "10. " + Fore.YELLOW + "Vigenère Decode      [-]" + Style.RESET_ALL)
  339.         print(Style.BRIGHT + "11. " + Fore.GREEN + "Fernet Encode        [+]" + Style.RESET_ALL)
  340.         print(Style.BRIGHT + "12. " + Fore.YELLOW + "Fernet Decode        [-]" + Style.RESET_ALL)
  341.         print(Style.BRIGHT + " 0. " + Fore.RED + "Exit                 [!]" + Style.RESET_ALL)
  342.  
  343.         choice = input(Style.BRIGHT +"\nEnter your choice (1-12)\nOr... type '0' to EXIT:  " + Style.RESET_ALL)
  344.  
  345.         if choice == '1' or choice == '2':
  346.             mode = choice
  347.             text = input("\nEnter the text: ")
  348.             shift = int(input("\nEnter the shift value: "))
  349.             print("\nEncoded/Decoded text:", caesar_cipher(text, shift, mode))
  350.         elif choice == '3' or choice == '4':
  351.             mode = choice
  352.             if mode == '3':
  353.                 text = input("\nEnter the plaintext to encode: ")
  354.             else:
  355.                 text = input("\nEnter the ciphertext to decode: ")
  356.             print("\nEncoded/Decoded text:", a1z26_cipher(text, mode))
  357.         elif choice == '5' or choice == '6':
  358.             mode = choice
  359.             if mode == '5':
  360.                 text = input("\nEnter the plaintext to encode: ")
  361.             else:
  362.                 text = input("\nEnter the ciphertext to decode: ")
  363.             print("\nEncoded/Decoded text:", atbash_cipher(text, mode))
  364.         elif choice == '7':
  365.             text = input("\nEnter the plaintext to encode: ")
  366.             key = int(input("\nEnter the number of rails: "))
  367.             print("\nEncoded text:", encode_RailFence(text, key))
  368.         elif choice == '8':
  369.             text = input("\nEnter the ciphertext to decode: ")
  370.             key = int(input("\nEnter the number of rails: "))
  371.             print("\nDecoded text:", decode_RailFence(text, key))
  372.         elif choice == '9' or choice == '10':
  373.             mode = choice
  374.             if mode == '9':
  375.                 text = input("\nEnter the plaintext to encode: ")
  376.             else:
  377.                 text = input("\nEnter the ciphertext to decode: ")
  378.             key = input("\nEnter the key: ")
  379.             print("\nEncoded/Decoded text:", vigenere_cipher(text, key, mode))
  380.         elif choice == '11':
  381.             key = fernet_encode()
  382.             if key is not None:
  383.                 text = input("\nEnter the text to encode using Fernet: ")
  384.                 cipher_suite = Fernet(key)
  385.                 encoded_text = cipher_suite.encrypt(text.encode())
  386.                 print("\nEncoded text:\n", encoded_text.decode())
  387.                 break  # Exit the loop after encoding
  388.         elif choice == '12':
  389.             key = fernet_decode()
  390.             if key is not None:
  391.                 encoded_text = input("\nEnter the text to decode using Fernet: ")
  392.                 cipher_suite = Fernet(key)
  393.                 decoded_text = cipher_suite.decrypt(encoded_text.encode()).decode()
  394.                 print("\nDecoded text:\n", decoded_text)
  395.                 break  # Exit the loop after decoding
  396.         elif choice == '0':
  397.             print()
  398.             print("-" * 28)
  399.             print("Exiting Program...  Goodbye!")
  400.             print("-" * 28)
  401.             break
  402.         else:
  403.             print("\nInvalid choice! Please enter a number between 1 and 12.\n")
  404.        
  405.         input("\nPress [ENTER] to continue...\n\n")
  406.        
  407. if __name__ == "__main__":
  408.     main()
  409.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement