-
-
Notifications
You must be signed in to change notification settings - Fork 45.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cipher: add scytale cipher #12395
base: master
Are you sure you want to change the base?
cipher: add scytale cipher #12395
Changes from all commits
e5f35aa
575ba8b
29a6da0
47adce5
a23b0f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide descriptive name for the parameter: |
||
ciphertext = "".join([grid[i] for i in sorted_key_indices]) | ||
|
||
return ciphertext | ||
|
||
|
||
def decrypt_columnar_cipher(ciphertext: str, key: str) -> str: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file |
||
""" | ||
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]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide descriptive name for the parameter: |
||
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) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
def encrypt_scytale_cipher(message: str, key: int) -> str: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file |
||
""" | ||
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: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file |
||
""" | ||
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) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As there is no test file in this pull request nor any test function or class in the file
ciphers/columnar_transposition_cipher.py
, please provide doctest for the functionencrypt_columnar_cipher