mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-02-20 00:02:04 +00:00
Merge a23b0f5177
into 6c92c5a539
This commit is contained in:
commit
370cb32fdd
74
ciphers/columnar_transposition_cipher.py
Normal file
74
ciphers/columnar_transposition_cipher.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
import math
|
||||
|
||||
|
||||
def encrypt_columnar_cipher(message: str, key: str) -> str:
|
||||
"""
|
||||
Encrypts a message using the Columnar Transposition Cipher.
|
||||
|
||||
:param message: Text to encrypt.
|
||||
:param key: String key used to define column order.
|
||||
:return: Encrypted message.
|
||||
"""
|
||||
# Remove spaces and calculate dimensions
|
||||
message = message.replace(" ", "")
|
||||
num_cols = len(key)
|
||||
num_rows = math.ceil(len(message) / num_cols)
|
||||
|
||||
# Fill the grid with characters
|
||||
grid = [""] * num_cols
|
||||
for i, char in enumerate(message):
|
||||
grid[i % num_cols] += char
|
||||
|
||||
# Sort columns based on the key order
|
||||
sorted_key_indices = sorted(range(len(key)), key=lambda k: key[k])
|
||||
ciphertext = "".join([grid[i] for i in sorted_key_indices])
|
||||
|
||||
return ciphertext
|
||||
|
||||
|
||||
def decrypt_columnar_cipher(ciphertext: str, key: str) -> str:
|
||||
"""
|
||||
Decrypts a message encrypted with the Columnar Transposition Cipher.
|
||||
|
||||
:param ciphertext: Encrypted text.
|
||||
:param key: String key used to define column order.
|
||||
:return: Decrypted message.
|
||||
"""
|
||||
num_cols = len(key)
|
||||
num_rows = math.ceil(len(ciphertext) / num_cols)
|
||||
num_shaded_boxes = (num_cols * num_rows) - len(ciphertext)
|
||||
|
||||
# Sort columns based on the key order
|
||||
sorted_key_indices = sorted(range(len(key)), key=lambda k: key[k])
|
||||
col_lengths = [num_rows] * num_cols
|
||||
for i in range(num_shaded_boxes):
|
||||
col_lengths[sorted_key_indices[-(i + 1)]] -= 1
|
||||
|
||||
# Distribute ciphertext into columns based on the sorted key
|
||||
grid = []
|
||||
start = 0
|
||||
for col_length in col_lengths:
|
||||
grid.append(ciphertext[start : start + col_length])
|
||||
start += col_length
|
||||
|
||||
# Rebuild plaintext row by row
|
||||
plaintext = ""
|
||||
for i in range(num_rows):
|
||||
for j in range(num_cols):
|
||||
if i < len(grid[sorted_key_indices[j]]):
|
||||
plaintext += grid[sorted_key_indices[j]][i]
|
||||
|
||||
return plaintext
|
||||
|
||||
|
||||
# Example usage
|
||||
message = "HELLO WORLD FROM COLUMNAR"
|
||||
key = "3412"
|
||||
|
||||
# Encrypt the message
|
||||
encrypted = encrypt_columnar_cipher(message, key)
|
||||
print("Encrypted:", encrypted)
|
||||
|
||||
# Decrypt the message
|
||||
decrypted = decrypt_columnar_cipher(encrypted, key)
|
||||
print("Decrypted:", decrypted)
|
59
ciphers/scytale_cipher.py
Normal file
59
ciphers/scytale_cipher.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
def encrypt_scytale_cipher(message: str, key: int) -> str:
|
||||
"""
|
||||
Encrypts a message using the Scytale Cipher.
|
||||
|
||||
:param message: Text to encrypt.
|
||||
:param key: Number of rows (key).
|
||||
:return: Encrypted message.
|
||||
"""
|
||||
message = message.replace(" ", "") # Optional: remove spaces
|
||||
ciphertext = [""] * key
|
||||
|
||||
# Distribute characters across rows based on the key
|
||||
for i in range(len(message)):
|
||||
ciphertext[i % key] += message[i]
|
||||
|
||||
return "".join(ciphertext)
|
||||
|
||||
|
||||
def decrypt_scytale_cipher(ciphertext: str, key: int) -> str:
|
||||
"""
|
||||
Decrypts a message encrypted with the Scytale Cipher.
|
||||
|
||||
:param ciphertext: Encrypted text.
|
||||
:param key: Number of rows (key).
|
||||
:return: Decrypted message.
|
||||
"""
|
||||
num_cols = -(-len(ciphertext) // key) # Calculate number of columns (round up)
|
||||
num_rows = key
|
||||
num_shaded_boxes = (num_cols * num_rows) - len(ciphertext) # Extra unused boxes
|
||||
|
||||
plaintext = [""] * num_cols
|
||||
col = 0
|
||||
row = 0
|
||||
|
||||
# Rebuild the plaintext row by row
|
||||
for char in ciphertext:
|
||||
plaintext[col] += char
|
||||
col += 1
|
||||
# Reset column and move to next row if end of column is reached
|
||||
if (col == num_cols) or (
|
||||
col == num_cols - 1 and row >= num_rows - num_shaded_boxes
|
||||
):
|
||||
col = 0
|
||||
row += 1
|
||||
|
||||
return "".join(plaintext)
|
||||
|
||||
|
||||
# Example usage
|
||||
message = "HELLO WORLD FROM SCYTALE"
|
||||
key = 5
|
||||
|
||||
# Encrypt the message
|
||||
ciphered = encrypt_scytale_cipher(message, key)
|
||||
print("Encrypted:", ciphered)
|
||||
|
||||
# Decrypt the message
|
||||
deciphered = decrypt_scytale_cipher(ciphered, key)
|
||||
print("Decrypted:", deciphered)
|
Loading…
Reference in New Issue
Block a user