Skip to content

Commit cbffc58

Browse files
authored
Create spiral_transposition.py
spiral_transposition.py for hacktoberfest
1 parent 788d95b commit cbffc58

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

ciphers/spiral_transposition.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# spiral_transposition.py
2+
3+
from __future__ import annotations
4+
import math
5+
6+
7+
def encrypt(plaintext: str) -> str:
8+
"""
9+
Encrypts text by writing it in a square matrix
10+
and reading characters in spiral order.
11+
"""
12+
text = "".join(ch for ch in plaintext.upper() if ch.isalpha())
13+
n = math.ceil(math.sqrt(len(text)))
14+
matrix = [["X"] * n for _ in range(n)]
15+
16+
idx = 0
17+
for r in range(n):
18+
for c in range(n):
19+
if idx < len(text):
20+
matrix[r][c] = text[idx]
21+
idx += 1
22+
23+
result = []
24+
top, left, bottom, right = 0, 0, n - 1, n - 1
25+
while top <= bottom and left <= right:
26+
for c in range(left, right + 1):
27+
result.append(matrix[top][c])
28+
top += 1
29+
for r in range(top, bottom + 1):
30+
result.append(matrix[r][right])
31+
right -= 1
32+
if top <= bottom:
33+
for c in range(right, left - 1, -1):
34+
result.append(matrix[bottom][c])
35+
bottom -= 1
36+
if left <= right:
37+
for r in range(bottom, top - 1, -1):
38+
result.append(matrix[r][left])
39+
left += 1
40+
return "".join(result)
41+
42+
43+
def decrypt(cipher_text: str) -> str:
44+
"""
45+
Attempts to reconstruct the original message by reversing the spiral order.
46+
"""
47+
L = len(cipher_text)
48+
n = math.ceil(math.sqrt(L))
49+
matrix = [[None] * n for _ in range(n)]
50+
51+
top, left, bottom, right = 0, 0, n - 1, n - 1
52+
idx = 0
53+
while top <= bottom and left <= right:
54+
for c in range(left, right + 1):
55+
matrix[top][c] = cipher_text[idx]
56+
idx += 1
57+
top += 1
58+
for r in range(top, bottom + 1):
59+
matrix[r][right] = cipher_text[idx]
60+
idx += 1
61+
right -= 1
62+
if top <= bottom:
63+
for c in range(right, left - 1, -1):
64+
matrix[bottom][c] = cipher_text[idx]
65+
idx += 1
66+
bottom -= 1
67+
if left <= right:
68+
for r in range(bottom, top - 1, -1):
69+
matrix[r][left] = cipher_text[idx]
70+
idx += 1
71+
left += 1
72+
73+
result = []
74+
for row in matrix:
75+
for ch in row:
76+
if ch:
77+
result.append(ch)
78+
return "".join(result)
79+
80+
81+
if __name__ == "__main__":
82+
while True:
83+
print("\n" + "-" * 10 + "\nSpiral Transposition Cipher\n" + "-" * 10)
84+
print("1. Encrypt\n2. Decrypt\n3. Quit")
85+
choice = input("Choice: ").strip()
86+
if choice == "1":
87+
pt = input("Plaintext: ")
88+
print("Ciphertext:", encrypt(pt))
89+
elif choice == "2":
90+
ct = input("Ciphertext: ")
91+
print("Recovered:", decrypt(ct))
92+
elif choice == "3":
93+
break
94+
else:
95+
print("Invalid option.")

0 commit comments

Comments
 (0)