Advertisement
Python253

cipher_tool

May 6th, 2024
904
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.74 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Filename: cipher_tool.py
  4. # Version: 1.0.0
  5. # Author: Jeoi Reqi
  6.  
  7. """
  8. This script serves as a comprehensive tool for encoding and decoding various classical ciphers.
  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. Requirements:
  32.    - Python 3.x
  33.    - Colorama (install with 'pip install colorama')
  34.    
  35. Usage:
  36.    - Run the script and choose a cipher type by entering the corresponding number.
  37.    - Follow the prompts to enter the text and any required parameters.
  38.    - The script will output the encoded or decoded text.
  39.  
  40. Additional Notes:
  41.    - For Rail Fence cipher, the number of rails must be a positive integer.
  42.    - For Vigenère cipher, the key should be a string of alphabetic characters.
  43.    - For A1Z26 cipher:
  44.        - When encoding, the input text should consist of alphabetic characters.
  45.        - When decoding, the input text should consist of numeric characters separated by spaces.
  46. """
  47.  
  48. #IMPORTS
  49. from colorama import Fore, Style
  50.  
  51. # CAESAR CIPHER
  52. def caesar_cipher(text, shift, mode):
  53.     """
  54.    Caesar cipher encoding or decoding.
  55.  
  56.    Args:
  57.        text (str): The text to be encoded or decoded.
  58.        shift (int): The shift value for encoding or decoding.
  59.        mode (str): '1' for encoding, '2' for decoding.
  60.  
  61.    Returns:
  62.        str: The encoded or decoded text.
  63.    """
  64.     result = ""
  65.     for char in text:
  66.         if char.isalpha():
  67.             if mode == '1':  # Encode
  68.                 if char.islower():
  69.                     result += chr((ord(char) - 97 + shift) % 26 + 97)
  70.                 else:
  71.                     result += chr((ord(char) - 65 + shift) % 26 + 65)
  72.             elif mode == '2':  # Decode
  73.                 if char.islower():
  74.                     result += chr((ord(char) - 97 - shift) % 26 + 97)
  75.                 else:
  76.                     result += chr((ord(char) - 65 - shift) % 26 + 65)
  77.         else:
  78.             result += char
  79.     return result
  80.  
  81. # A1Z26 CIPHER
  82. def a1z26_cipher(text, mode):
  83.     """
  84.    A1Z26 cipher encoding or decoding.
  85.  
  86.    Args:
  87.        text (str): The text to be encoded or decoded.
  88.        mode (str): '3' for encoding, '4' for decoding.
  89.  
  90.    Returns:
  91.        str: The encoded or decoded text.
  92.    """
  93.     if mode == '3':    # ENCODE
  94.         result = ' '.join(str(ord(char) - 96) if char.isalpha() else '0' for char in text)
  95.     elif mode == '4':  # DECODE
  96.         result = ''
  97.         nums = text.split()
  98.         for num in nums:
  99.             if num == '0':
  100.                 result += ' '
  101.             else:
  102.                 result += chr(int(num) + 96)
  103.     else:
  104.         result = "\nInvalid mode! Please choose '3' for encoding or '4' for decoding.\n"
  105.     return result
  106.  
  107. # ATBASH CIPHER
  108. def atbash_cipher(text, mode):
  109.     """
  110.    Atbash cipher encoding or decoding.
  111.  
  112.    Args:
  113.        text (str): The text to be encoded or decoded.
  114.        mode (str): '5' for encoding, '6' for decoding.
  115.  
  116.    Returns:
  117.        str: The encoded or decoded text.
  118.    """
  119.     result = ""
  120.     for char in text:
  121.         if char.isalpha():
  122.             if char.islower():
  123.                 result += chr(122 - ord(char) + 97)
  124.             else:
  125.                 result += chr(90 - ord(char) + 65)
  126.         else:
  127.             result += char
  128.     return result
  129.  
  130. # RAILFENCE CIPHER (ENCODE)
  131. def encode_RailFence(text, key):
  132.     """
  133.    Rail Fence cipher encoding.
  134.  
  135.    Args:
  136.        text (str): The text to be encoded.
  137.        key (int): The number of rails.
  138.  
  139.    Returns:
  140.        str: The encoded text.
  141.    """
  142.     rail = [['\n' for i in range(len(text))] for j in range(key)]
  143.     dir_down = False
  144.     row, col = 0, 0
  145.      
  146.     for i in range(len(text)):
  147.         if (row == 0) or (row == key - 1):
  148.             dir_down = not dir_down
  149.          
  150.         rail[row][col] = text[i]
  151.         col += 1
  152.          
  153.         if dir_down:
  154.             row += 1
  155.         else:
  156.             row -= 1
  157.    
  158.     result = []
  159.     for i in range(key):
  160.         for j in range(len(text)):
  161.             if rail[i][j] != '\n':
  162.                 result.append(rail[i][j])
  163.     return ''.join(result)
  164.  
  165. # RAILFENCE CIPHER (DECODE)
  166. def decode_RailFence(cipher, key):
  167.     """
  168.    Rail Fence cipher decoding.
  169.  
  170.    Args:
  171.        cipher (str): The text to be decoded.
  172.        key (int): The number of rails.
  173.  
  174.    Returns:
  175.        str: The decoded text.
  176.    """
  177.     rail = [['\n' for i in range(len(cipher))] for j in range(key)]
  178.     dir_down = None
  179.     row, col = 0, 0
  180.      
  181.     for i in range(len(cipher)):
  182.         if row == 0:
  183.             dir_down = True
  184.         if row == key - 1:
  185.             dir_down = False
  186.          
  187.         rail[row][col] = '*'
  188.         col += 1
  189.          
  190.         if dir_down:
  191.             row += 1
  192.         else:
  193.             row -= 1
  194.              
  195.     index = 0
  196.     for i in range(key):
  197.         for j in range(len(cipher)):
  198.             if (rail[i][j] == '*') and (index < len(cipher)):
  199.                 rail[i][j] = cipher[index]
  200.                 index += 1
  201.          
  202.     result = []
  203.     row, col = 0, 0
  204.     for i in range(len(cipher)):
  205.         if row == 0:
  206.             dir_down = True
  207.         if row == key - 1:
  208.             dir_down = False
  209.              
  210.         if rail[row][col] != '*':
  211.             result.append(rail[row][col])
  212.             col += 1
  213.              
  214.         if dir_down:
  215.             row += 1
  216.         else:
  217.             row -= 1
  218.     return ''.join(result)
  219.  
  220. # VIGENERE CIPHER
  221. def vigenere_cipher(text, key, mode):
  222.     """
  223.    Vigenère cipher encoding or decoding.
  224.  
  225.    Args:
  226.        text (str): The text to be encoded or decoded.
  227.        key (str): The key for encoding or decoding.
  228.        mode (str): '9' for encoding, '10' for decoding.
  229.  
  230.    Returns:
  231.        str: The encoded or decoded text.
  232.    """
  233.     result = ""
  234.     key_length = len(key)
  235.     key_index = 0
  236.     for char in text:
  237.         if char.isalpha():
  238.             if mode == '9':  # Encode
  239.                 if char.islower():
  240.                     shift = ord(key[key_index].lower()) - 97
  241.                     result += chr((ord(char) - 97 + shift) % 26 + 97)
  242.                 else:
  243.                     shift = ord(key[key_index].lower()) - 97
  244.                     result += chr((ord(char) - 65 + shift) % 26 + 65)
  245.             elif mode == '10':  # Decode
  246.                 if char.islower():
  247.                     shift = ord(key[key_index].lower()) - 97
  248.                     result += chr((ord(char) - 97 - shift) % 26 + 97)
  249.                 else:
  250.                     shift = ord(key[key_index].lower()) - 97
  251.                     result += chr((ord(char) - 65 - shift) % 26 + 65)
  252.             key_index = (key_index + 1) % key_length
  253.         else:
  254.             result += char
  255.     return result
  256.  
  257. # PREPARE TEXT
  258. def prepare_text(text):
  259.     """
  260.    Prepare text for encoding.
  261.  
  262.    Args:
  263.        text (str): The text to be prepared.
  264.  
  265.    Returns:
  266.        str: The prepared text.
  267.    """
  268.     # Remove non-alphabetic characters and convert to uppercase
  269.     cleaned_text = ''.join(char.upper() for char in text if char.isalpha())
  270.     # Replace 'J' with 'I'
  271.     cleaned_text = cleaned_text.replace('J', 'I')
  272.     return cleaned_text
  273.  
  274. # MAIN MENU & FUNCTION CALLS
  275. def main():
  276.     """
  277.    Main function to run the cipher tool.
  278.    """
  279.     while True:
  280.         print("-" * 28)
  281.         print(Style.BRIGHT + Fore.GREEN + "     :: CIPHER TOOL ::" + Style.RESET_ALL)
  282.         print("-" * 28)
  283.         print(Style.BRIGHT +"\nCHOOSE A CIPHER TYPE:\n" + Style.RESET_ALL)
  284.         print(Style.BRIGHT + "01. " + Fore.GREEN + "Caesar Encode        [+]" + Style.RESET_ALL)
  285.         print(Style.BRIGHT + "02. " + Fore.YELLOW + "Caesar Decode        [-]" + Style.RESET_ALL)
  286.         print(Style.BRIGHT + "03. " + Fore.GREEN + "A1Z26 Encode         [+]" + Style.RESET_ALL)
  287.         print(Style.BRIGHT + "04. " + Fore.YELLOW + "A1Z26 Decode         [-]" + Style.RESET_ALL)
  288.         print(Style.BRIGHT + "05. " + Fore.GREEN + "Atbash Encode        [+]" + Style.RESET_ALL)
  289.         print(Style.BRIGHT + "06. " + Fore.YELLOW + "Atbash Decode        [-]" + Style.RESET_ALL)
  290.         print(Style.BRIGHT + "07. " + Fore.GREEN + "Rail Fence Encode    [+]" + Style.RESET_ALL)
  291.         print(Style.BRIGHT + "08. " + Fore.YELLOW + "Rail Fence Decode    [-]" + Style.RESET_ALL)
  292.         print(Style.BRIGHT + "09. " + Fore.GREEN + "Vigenère Encode      [+]" + Style.RESET_ALL)
  293.         print(Style.BRIGHT + "10. " + Fore.YELLOW + "Vigenère Decode      [-]" + Style.RESET_ALL)
  294.         print(Style.BRIGHT + "0. " + Fore.RED + "Exit                  [!]" + Style.RESET_ALL)
  295.  
  296.         choice = input(Style.BRIGHT +"\nEnter your choice (1-10)\nOr... type '0' to EXIT:  " + Style.RESET_ALL)
  297.  
  298.         if choice == '1' or choice == '2':
  299.             mode = choice
  300.             text = input("\nEnter the text: ")
  301.             shift = int(input("\nEnter the shift value: "))
  302.             print("\nEncoded/Decoded text:", caesar_cipher(text, shift, mode))
  303.         elif choice == '3' or choice == '4':
  304.             mode = choice
  305.             if mode == '3':
  306.                 text = input("\nEnter the plaintext to encode: ")
  307.             else:
  308.                 text = input("\nEnter the ciphertext to decode: ")
  309.             print("\nEncoded/Decoded text:", a1z26_cipher(text, mode))
  310.         elif choice == '5' or choice == '6':
  311.             mode = choice
  312.             if mode == '5':
  313.                 text = input("\nEnter the plaintext to encode: ")
  314.             else:
  315.                 text = input("\nEnter the ciphertext to decode: ")
  316.             print("\nEncoded/Decoded text:", atbash_cipher(text, mode))
  317.         elif choice == '7':
  318.             text = input("\nEnter the plaintext to encode: ")
  319.             key = int(input("\nEnter the number of rails: "))
  320.             print("\nEncoded text:", encode_RailFence(text, key))
  321.         elif choice == '8':
  322.             text = input("\nEnter the ciphertext to decode: ")
  323.             key = int(input("\nEnter the number of rails: "))
  324.             print("\nDecoded text:", decode_RailFence(text, key))
  325.         elif choice == '9' or choice == '10':
  326.             mode = choice
  327.             if mode == '9':
  328.                 text = input("\nEnter the plaintext to encode: ")
  329.             else:
  330.                 text = input("\nEnter the ciphertext to decode: ")
  331.             key = input("\nEnter the key: ")
  332.             print("\nEncoded/Decoded text:", vigenere_cipher(text, key, mode))
  333.         elif choice == '0':
  334.             print()
  335.             print("-" * 28)
  336.             print("Exiting Program...  Goodbye!")
  337.             print("-" * 28)
  338.             break
  339.         else:
  340.             print("\nInvalid choice! Please enter a number between 1 and 13.\n")
  341.  
  342. if __name__ == "__main__":
  343.     main()
  344.  
  345.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement