Advertisement
Python253

railfence_cipher_tool

Jun 1st, 2024
624
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.01 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # Filename: railfence_cipher_tool.py
  4. # Version: 1.0.0
  5. # Author: Jeoi Reqi
  6.  
  7. """
  8. Description:
  9.    - This script provides a tool for encrypting and decrypting messages using the Rail Fence Cipher.
  10.    - Additionally, it has the option to encrypt & decrypt a demo cipher using a quote by Margaret Thatcher.
  11.  
  12. Requirements:
  13.    - Python 3.x
  14.    - The following modules:
  15.        - math
  16.        - itertools
  17.        
  18. Functions:
  19.    - main():
  20.        The main function to run the program and interact with the user.
  21.    - encrypt_message(plaintext):
  22.        Encrypts a message using the Rail Fence Cipher.
  23.    - prep_plaintext(plaintext):
  24.        Removes spaces and converts the message to uppercase.
  25.    - build_rails(message):
  26.        Builds strings with every other letter in a message.
  27.    - decrypt_message(ciphertext):
  28.        Decrypts a message using the Rail Fence Cipher.
  29.    - prep_ciphertext(ciphertext):
  30.        Removes whitespace from the ciphertext.
  31.    - split_rails(message):
  32.        Splits the message into two parts for decryption.
  33.    - decrypt(row1, row2):
  34.        Builds the plaintext from two rows of ciphertext.
  35.    - run_demo():
  36.        Runs a demo with provided ciphertext.
  37.  
  38. Usage:
  39.    - Run the script and follow the on-screen menu to encrypt or decrypt messages using the Rail Fence Cipher.
  40.  
  41. Additional Notes:
  42.    - The Rail Fence Cipher is a transposition cipher that encrypts and decrypts messages by writing the characters in a zigzag pattern.
  43.    - In the Rail Fence Cipher, the plaintext is written diagonally up and down in a zigzag pattern on successive "rails" of an imaginary fence, then read off row by row to produce the ciphertext.
  44. """
  45.  
  46. import math
  47. import itertools
  48.  
  49. def main():
  50.     """Run program."""
  51.     while True:
  52.         print("_" * 21)
  53.         print("\nRailfence Cipher Menu")
  54.         print("_" * 21, "\n")
  55.         print("1. Run Demo")
  56.         print("2. Encrypt a message")
  57.         print("3. Decrypt a message")
  58.         print("0. Exit")
  59.         choice = input("\nEnter your choice: ")
  60.  
  61.         if choice == '1':
  62.             run_demo()
  63.         elif choice == '2':
  64.             plaintext = input("Enter the plaintext to encrypt: ")
  65.             print()
  66.             encrypt_message(plaintext)
  67.         elif choice == '3':
  68.             ciphertext = input("Enter the ciphertext to decrypt: ")
  69.             print()
  70.             decrypt_message(ciphertext)
  71.         elif choice == '0':
  72.             print()
  73.             print("_" * 21)
  74.             print("\nExiting program...\n\n   👋     GoodBye!")
  75.             print("_" * 21, "\n")
  76.             break
  77.         else:
  78.             print("Invalid choice. Please enter 1, 2, 3, or 4.")
  79.  
  80. def encrypt_message(plaintext):
  81.     """Encrypt a message using rail fence cipher."""
  82.     message = prep_plaintext(plaintext)
  83.     rails = build_rails(message)
  84.     ciphertext = ' '.join([rails[i:i+5] for i in range(0, len(rails), 5)])
  85.     print("ENCODED (Ciphertext):   {}".format(ciphertext))
  86.     print("FORMATTED (Ciphertext): {}".format(ciphertext.replace(" ", "").lower()))
  87.  
  88. def prep_plaintext(plaintext):
  89.     """Remove spaces & leading/trailing whitespace."""
  90.     message = "".join(plaintext.split())
  91.     message = message.upper()  # convention for ciphertext is uppercase
  92.     return message
  93.  
  94. def build_rails(message):
  95.     """Build strings with every other letter in a message."""
  96.     evens = message[::2]
  97.     odds = message[1::2]
  98.     rails = evens + odds
  99.     return rails
  100.  
  101. def decrypt_message(ciphertext):
  102.     """Decrypt a message using rail fence cipher."""
  103.     formatted_ciphertext = ciphertext.replace(" ", "")
  104.     print("ENCODED (Formatted): ", formatted_ciphertext.lower())
  105.    
  106.     message = prep_ciphertext(ciphertext)
  107.     row1, row2 = split_rails(message)
  108.     decrypt(row1, row2)
  109.  
  110. def prep_ciphertext(ciphertext):
  111.     """Remove whitespace."""
  112.     message = "".join(ciphertext.split())
  113.     return message
  114.  
  115. def split_rails(message):
  116.     """Split message in two, always rounding UP for 1st row."""
  117.     row_1_len = math.ceil(len(message)/2)
  118.     row1 = (message[:row_1_len]).lower()
  119.     row2 = (message[row_1_len:]).lower()
  120.     return row1, row2
  121.  
  122. def decrypt(row1, row2):
  123.     """Build list with every other letter in 2 strings & print."""
  124.     plaintext = []
  125.     for r1, r2 in itertools.zip_longest(row1, row2):
  126.         plaintext.append(r1)
  127.         plaintext.append(r2)
  128.     if None in plaintext:
  129.         plaintext.pop()
  130.     print("DECODED (Plaintext):  {}".format(''.join(plaintext)))
  131.  
  132. def run_demo():
  133.     """Run demo with provided ciphertext."""
  134.     ciphertext = """YUNIO EYODR ALBTC NMSSR VLNNR SRCUE -AGRT HTHRO ADCMB RAORI ,UEOO ITTAE OIFAT UTR.M RAETA CE"""
  135.     formatted_ciphertext = ciphertext.replace(" ", "")
  136.    
  137.     print("\nCIPHERTEXT: ", ciphertext, "\n")
  138.     print("ENCODED (Formatted): ", formatted_ciphertext.lower())
  139.    
  140.     message = prep_ciphertext(ciphertext)
  141.     row1, row2 = split_rails(message)
  142.     decrypt(row1, row2)
  143.  
  144. if __name__ == '__main__':
  145.     main()
  146.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement