fork download
  1. import random
  2. import string
  3.  
  4. # Function to generate a random substitution cipher key
  5. def generate_substitution_key():
  6. alphabet = string.ascii_lowercase
  7. shuffled = list(alphabet)
  8. random.shuffle(shuffled)
  9. return dict(zip(alphabet, shuffled))
  10.  
  11. # Substitution cipher
  12. def substitution_encrypt(plaintext, substitution_key):
  13. encrypted_text = ""
  14. for char in plaintext.lower():
  15. if char in substitution_key:
  16. encrypted_text += substitution_key[char]
  17. else:
  18. encrypted_text += char # Non-alphabetic characters remain unchanged
  19. return encrypted_text
  20.  
  21. # Substitution cipher decryption
  22. def substitution_decrypt(encrypted_text, substitution_key):
  23. reversed_key = {v: k for k, v in substitution_key.items()}
  24. decrypted_text = ""
  25. for char in encrypted_text.lower():
  26. if char in reversed_key:
  27. decrypted_text += reversed_key[char]
  28. else:
  29. decrypted_text += char # Non-alphabetic characters remain unchanged
  30. return decrypted_text
  31.  
  32. # Function to perform a transposition cipher
  33. def transposition_encrypt(plaintext, key):
  34. # Create a grid with key columns
  35. grid = [''] * key
  36. for i in range(len(plaintext)):
  37. grid[i % key] += plaintext[i]
  38.  
  39. # Combine the columns into the final encrypted text
  40. encrypted_text = ''.join(grid)
  41. return encrypted_text
  42.  
  43. # Transposition cipher decryption
  44. def transposition_decrypt(encrypted_text, key):
  45. # Calculate number of rows in the grid
  46. num_rows = len(encrypted_text) // key
  47. num_extra_chars = len(encrypted_text) % key
  48.  
  49. # Create a list of rows, and initialize the list of columns
  50. grid = [''] * num_rows
  51. column = 0
  52. row = 0
  53.  
  54. # Distribute characters from encrypted text into grid based on transposition key
  55. for char in encrypted_text:
  56. grid[row] += char
  57. row += 1
  58. if row == num_rows:
  59. row = 0
  60. column += 1
  61.  
  62. # Rebuild the plaintext by reading characters column by column
  63. decrypted_text = ''.join(''.join(row) for row in grid)
  64.  
  65. return decrypted_text
  66.  
  67. # Product Cipher (Substitution + Transposition)
  68. def product_cipher_encrypt(plaintext, substitution_key, transposition_key):
  69. # Step 1: Apply substitution cipher
  70. substituted_text = substitution_encrypt(plaintext, substitution_key)
  71.  
  72. # Step 2: Apply transposition cipher
  73. encrypted_text = transposition_encrypt(substituted_text, transposition_key)
  74.  
  75. return encrypted_text
  76.  
  77. # Product Cipher Decryption (reverse of the encryption process)
  78. def product_cipher_decrypt(encrypted_text, substitution_key, transposition_key):
  79. # Step 1: Apply transposition cipher decryption
  80. decrypted_text = transposition_decrypt(encrypted_text, transposition_key)
  81.  
  82. # Step 2: Apply substitution cipher decryption
  83. decrypted_text = substitution_decrypt(decrypted_text, substitution_key)
  84.  
  85. return decrypted_text
  86.  
  87. # Example usage
  88. if __name__ == "__main__":
  89. # Example plaintext
  90. plaintext = "hello world"
  91.  
  92. # Generate random substitution cipher key
  93. substitution_key = generate_substitution_key()
  94.  
  95. # Set a transposition key (number of columns for transposition)
  96. transposition_key = 5
  97.  
  98. print("Plaintext:", plaintext)
  99.  
  100. # Encrypt the plaintext using product cipher
  101. encrypted_text = product_cipher_encrypt(plaintext, substitution_key, transposition_key)
  102. print("Encrypted Text:", encrypted_text)
  103.  
  104. # Decrypt the encrypted text using product cipher
  105. decrypted_text = product_cipher_decrypt(encrypted_text, substitution_key, transposition_key)
  106. print("Decrypted Text:", decrypted_text)
  107.  
  108. # Verify that the decrypted text matches the original plaintext
  109. assert decrypted_text == plaintext, "Decrypted text does not match plaintext!"
  110. print("Decryption is successful. The decrypted text matches the original plaintext.")
  111.  
Success #stdin #stdout 0.01s 9708KB
stdin
Standard input is empty
stdout
('Plaintext:', 'hello world')
('Encrypted Text:', 't qomvgvbgv')
('Decrypted Text:', 'hdworl ello')
Decryption is successful. The decrypted text matches the original plaintext.