-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinteractive.py
More file actions
160 lines (120 loc) · 3.73 KB
/
Copy pathinteractive.py
File metadata and controls
160 lines (120 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
from rich.console import Console
from rich.panel import Panel
from rich.prompt import Prompt
from rich.table import Table
import string
console = Console()
def build_matrix(keyword, merge_choice):
keyword = keyword.upper().replace(" ", "")
remove_letter = "J" if merge_choice == "I" else "I"
seen = set()
key_string = ""
for ch in keyword:
if ch == remove_letter:
ch = merge_choice
if ch not in seen and ch.isalpha():
seen.add(ch)
key_string += ch
for ch in string.ascii_uppercase:
if ch == remove_letter:
continue
if ch not in seen:
seen.add(ch)
key_string += ch
matrix = [list(key_string[i : i + 5]) for i in range(0, 25, 5)]
return matrix
def preprocess_text(text, merge_choice):
text = text.upper().replace(" ", "")
replace_letter = "J" if merge_choice == "I" else "I"
text = text.replace(replace_letter, merge_choice)
pairs = []
i = 0
while i < len(text):
a = text[i]
b = text[i + 1] if i + 1 < len(text) else "X"
if a == b:
pairs.append(a + "X")
i += 1
else:
pairs.append(a + b)
i += 2
if len(pairs[-1]) == 1:
pairs[-1] += "X"
return pairs
def find_position(matrix, letter):
for r in range(5):
for c in range(5):
if matrix[r][c] == letter:
return r, c
def encrypt(matrix, pairs):
cipher = ""
for a, b in pairs:
r1, c1 = find_position(matrix, a)
r2, c2 = find_position(matrix, b)
if r1 == r2:
cipher += matrix[r1][(c1 + 1) % 5]
cipher += matrix[r2][(c2 + 1) % 5]
elif c1 == c2:
cipher += matrix[(r1 + 1) % 5][c1]
cipher += matrix[(r2 + 1) % 5][c2]
else:
cipher += matrix[r1][c2]
cipher += matrix[r2][c1]
return cipher
def decrypt(matrix, pairs):
plain = ""
for a, b in pairs:
r1, c1 = find_position(matrix, a)
r2, c2 = find_position(matrix, b)
if r1 == r2:
plain += matrix[r1][(c1 - 1) % 5]
plain += matrix[r2][(c2 - 1) % 5]
elif c1 == c2:
plain += matrix[(r1 - 1) % 5][c1]
plain += matrix[(r2 - 1) % 5][c2]
else:
plain += matrix[r1][c2]
plain += matrix[r2][c1]
return plain
def display_matrix(matrix):
table = Table(title="🔑 Key Matrix", show_header=False)
for _ in range(5):
table.add_column(justify="center")
for row in matrix:
table.add_row(*row)
console.print(table)
def main():
console.clear()
console.print(
Panel.fit(
"[bold cyan]🔐 Playfair Cipher Tool[/bold cyan]",
border_style="cyan",
)
)
keyword = Prompt.ask("\n[bold yellow]Enter keyword[/bold yellow]")
merge_choice = Prompt.ask(
"[bold yellow]Merge I/J as which letter?[/bold yellow]",
choices=["I", "J"],
default="I",
)
matrix = build_matrix(keyword, merge_choice)
console.print()
display_matrix(matrix)
mode = Prompt.ask(
"\n[bold yellow]Choose mode[/bold yellow]", choices=["E", "D"], default="E"
)
message = Prompt.ask("[bold yellow]Enter message[/bold yellow]")
pairs = preprocess_text(message, merge_choice)
if mode == "E":
result = encrypt(matrix, pairs)
title = "Encrypted Message"
style = "bold green"
else:
result = decrypt(matrix, pairs)
title = "Decrypted Message"
style = "bold magenta"
console.print(
Panel(f"[{style}]{result}[/{style}]", title=f" {title}", border_style="blue")
)
if __name__ == "__main__":
main()