Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # Filename: cipher_tool.py
- # Version: 1.0.0
- # Author: Jeoi Reqi
- """
- This script serves as a comprehensive tool for encoding and decoding various classical ciphers.
- It offers functionalities for a range of encoding and decoding techniques for the following:
- 1: Caesar Cipher:
- - Allows encoding and decoding text by shifting characters a fixed number of positions in the alphabet.
- 2: A1Z26 Cipher:
- - For encoding, it converts alphabetic characters into their corresponding numeric positions in the alphabet.
- - During decoding, it reverses this process, converting numeric sequences back into alphabetic characters.
- - Note: Spaces in the encoded text are represented by '0'.
- 3: Atbash Cipher:
- - Inverts the alphabet, substituting each letter with its reverse counterpart.
- 4: Rail Fence Cipher:
- - Utilizes a transposition technique, encoding text by writing it in a zigzag pattern across a specified number of "rails".
- Then it reads off the encoded text row by row to decode to plaintext.
- 5: Vigenère Cipher:
- - Employs a keyword to encode text, shifting characters in a repeating pattern based on the keyword's letters.
- Decoding with Vigenère reverses this process, decrypting text based on the keyword.
- Requirements:
- - Python 3.x
- - Colorama (install with 'pip install colorama')
- Usage:
- - Run the script and choose a cipher type by entering the corresponding number.
- - Follow the prompts to enter the text and any required parameters.
- - The script will output the encoded or decoded text.
- Additional Notes:
- - For Rail Fence cipher, the number of rails must be a positive integer.
- - For Vigenère cipher, the key should be a string of alphabetic characters.
- - For A1Z26 cipher:
- - When encoding, the input text should consist of alphabetic characters.
- - When decoding, the input text should consist of numeric characters separated by spaces.
- """
- #IMPORTS
- from colorama import Fore, Style
- # CAESAR CIPHER
- def caesar_cipher(text, shift, mode):
- """
- Caesar cipher encoding or decoding.
- Args:
- text (str): The text to be encoded or decoded.
- shift (int): The shift value for encoding or decoding.
- mode (str): '1' for encoding, '2' for decoding.
- Returns:
- str: The encoded or decoded text.
- """
- result = ""
- for char in text:
- if char.isalpha():
- if mode == '1': # Encode
- if char.islower():
- result += chr((ord(char) - 97 + shift) % 26 + 97)
- else:
- result += chr((ord(char) - 65 + shift) % 26 + 65)
- elif mode == '2': # Decode
- if char.islower():
- result += chr((ord(char) - 97 - shift) % 26 + 97)
- else:
- result += chr((ord(char) - 65 - shift) % 26 + 65)
- else:
- result += char
- return result
- # A1Z26 CIPHER
- def a1z26_cipher(text, mode):
- """
- A1Z26 cipher encoding or decoding.
- Args:
- text (str): The text to be encoded or decoded.
- mode (str): '3' for encoding, '4' for decoding.
- Returns:
- str: The encoded or decoded text.
- """
- if mode == '3': # ENCODE
- result = ' '.join(str(ord(char) - 96) if char.isalpha() else '0' for char in text)
- elif mode == '4': # DECODE
- result = ''
- nums = text.split()
- for num in nums:
- if num == '0':
- result += ' '
- else:
- result += chr(int(num) + 96)
- else:
- result = "\nInvalid mode! Please choose '3' for encoding or '4' for decoding.\n"
- return result
- # ATBASH CIPHER
- def atbash_cipher(text, mode):
- """
- Atbash cipher encoding or decoding.
- Args:
- text (str): The text to be encoded or decoded.
- mode (str): '5' for encoding, '6' for decoding.
- Returns:
- str: The encoded or decoded text.
- """
- result = ""
- for char in text:
- if char.isalpha():
- if char.islower():
- result += chr(122 - ord(char) + 97)
- else:
- result += chr(90 - ord(char) + 65)
- else:
- result += char
- return result
- # RAILFENCE CIPHER (ENCODE)
- def encode_RailFence(text, key):
- """
- Rail Fence cipher encoding.
- Args:
- text (str): The text to be encoded.
- key (int): The number of rails.
- Returns:
- str: The encoded text.
- """
- rail = [['\n' for i in range(len(text))] for j in range(key)]
- dir_down = False
- row, col = 0, 0
- for i in range(len(text)):
- if (row == 0) or (row == key - 1):
- dir_down = not dir_down
- rail[row][col] = text[i]
- col += 1
- if dir_down:
- row += 1
- else:
- row -= 1
- result = []
- for i in range(key):
- for j in range(len(text)):
- if rail[i][j] != '\n':
- result.append(rail[i][j])
- return ''.join(result)
- # RAILFENCE CIPHER (DECODE)
- def decode_RailFence(cipher, key):
- """
- Rail Fence cipher decoding.
- Args:
- cipher (str): The text to be decoded.
- key (int): The number of rails.
- Returns:
- str: The decoded text.
- """
- rail = [['\n' for i in range(len(cipher))] for j in range(key)]
- dir_down = None
- row, col = 0, 0
- for i in range(len(cipher)):
- if row == 0:
- dir_down = True
- if row == key - 1:
- dir_down = False
- rail[row][col] = '*'
- col += 1
- if dir_down:
- row += 1
- else:
- row -= 1
- index = 0
- for i in range(key):
- for j in range(len(cipher)):
- if (rail[i][j] == '*') and (index < len(cipher)):
- rail[i][j] = cipher[index]
- index += 1
- result = []
- row, col = 0, 0
- for i in range(len(cipher)):
- if row == 0:
- dir_down = True
- if row == key - 1:
- dir_down = False
- if rail[row][col] != '*':
- result.append(rail[row][col])
- col += 1
- if dir_down:
- row += 1
- else:
- row -= 1
- return ''.join(result)
- # VIGENERE CIPHER
- def vigenere_cipher(text, key, mode):
- """
- Vigenère cipher encoding or decoding.
- Args:
- text (str): The text to be encoded or decoded.
- key (str): The key for encoding or decoding.
- mode (str): '9' for encoding, '10' for decoding.
- Returns:
- str: The encoded or decoded text.
- """
- result = ""
- key_length = len(key)
- key_index = 0
- for char in text:
- if char.isalpha():
- if mode == '9': # Encode
- if char.islower():
- shift = ord(key[key_index].lower()) - 97
- result += chr((ord(char) - 97 + shift) % 26 + 97)
- else:
- shift = ord(key[key_index].lower()) - 97
- result += chr((ord(char) - 65 + shift) % 26 + 65)
- elif mode == '10': # Decode
- if char.islower():
- shift = ord(key[key_index].lower()) - 97
- result += chr((ord(char) - 97 - shift) % 26 + 97)
- else:
- shift = ord(key[key_index].lower()) - 97
- result += chr((ord(char) - 65 - shift) % 26 + 65)
- key_index = (key_index + 1) % key_length
- else:
- result += char
- return result
- # PREPARE TEXT
- def prepare_text(text):
- """
- Prepare text for encoding.
- Args:
- text (str): The text to be prepared.
- Returns:
- str: The prepared text.
- """
- # Remove non-alphabetic characters and convert to uppercase
- cleaned_text = ''.join(char.upper() for char in text if char.isalpha())
- # Replace 'J' with 'I'
- cleaned_text = cleaned_text.replace('J', 'I')
- return cleaned_text
- # MAIN MENU & FUNCTION CALLS
- def main():
- """
- Main function to run the cipher tool.
- """
- while True:
- print("-" * 28)
- print(Style.BRIGHT + Fore.GREEN + " :: CIPHER TOOL ::" + Style.RESET_ALL)
- print("-" * 28)
- print(Style.BRIGHT +"\nCHOOSE A CIPHER TYPE:\n" + Style.RESET_ALL)
- print(Style.BRIGHT + "01. " + Fore.GREEN + "Caesar Encode [+]" + Style.RESET_ALL)
- print(Style.BRIGHT + "02. " + Fore.YELLOW + "Caesar Decode [-]" + Style.RESET_ALL)
- print(Style.BRIGHT + "03. " + Fore.GREEN + "A1Z26 Encode [+]" + Style.RESET_ALL)
- print(Style.BRIGHT + "04. " + Fore.YELLOW + "A1Z26 Decode [-]" + Style.RESET_ALL)
- print(Style.BRIGHT + "05. " + Fore.GREEN + "Atbash Encode [+]" + Style.RESET_ALL)
- print(Style.BRIGHT + "06. " + Fore.YELLOW + "Atbash Decode [-]" + Style.RESET_ALL)
- print(Style.BRIGHT + "07. " + Fore.GREEN + "Rail Fence Encode [+]" + Style.RESET_ALL)
- print(Style.BRIGHT + "08. " + Fore.YELLOW + "Rail Fence Decode [-]" + Style.RESET_ALL)
- print(Style.BRIGHT + "09. " + Fore.GREEN + "Vigenère Encode [+]" + Style.RESET_ALL)
- print(Style.BRIGHT + "10. " + Fore.YELLOW + "Vigenère Decode [-]" + Style.RESET_ALL)
- print(Style.BRIGHT + "0. " + Fore.RED + "Exit [!]" + Style.RESET_ALL)
- choice = input(Style.BRIGHT +"\nEnter your choice (1-10)\nOr... type '0' to EXIT: " + Style.RESET_ALL)
- if choice == '1' or choice == '2':
- mode = choice
- text = input("\nEnter the text: ")
- shift = int(input("\nEnter the shift value: "))
- print("\nEncoded/Decoded text:", caesar_cipher(text, shift, mode))
- elif choice == '3' or choice == '4':
- mode = choice
- if mode == '3':
- text = input("\nEnter the plaintext to encode: ")
- else:
- text = input("\nEnter the ciphertext to decode: ")
- print("\nEncoded/Decoded text:", a1z26_cipher(text, mode))
- elif choice == '5' or choice == '6':
- mode = choice
- if mode == '5':
- text = input("\nEnter the plaintext to encode: ")
- else:
- text = input("\nEnter the ciphertext to decode: ")
- print("\nEncoded/Decoded text:", atbash_cipher(text, mode))
- elif choice == '7':
- text = input("\nEnter the plaintext to encode: ")
- key = int(input("\nEnter the number of rails: "))
- print("\nEncoded text:", encode_RailFence(text, key))
- elif choice == '8':
- text = input("\nEnter the ciphertext to decode: ")
- key = int(input("\nEnter the number of rails: "))
- print("\nDecoded text:", decode_RailFence(text, key))
- elif choice == '9' or choice == '10':
- mode = choice
- if mode == '9':
- text = input("\nEnter the plaintext to encode: ")
- else:
- text = input("\nEnter the ciphertext to decode: ")
- key = input("\nEnter the key: ")
- print("\nEncoded/Decoded text:", vigenere_cipher(text, key, mode))
- elif choice == '0':
- print()
- print("-" * 28)
- print("Exiting Program... Goodbye!")
- print("-" * 28)
- break
- else:
- print("\nInvalid choice! Please enter a number between 1 and 13.\n")
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement