File size: 5,869 Bytes
b6b5db2 b33e052 b6b5db2 b33e052 b6b5db2 b33e052 b6b5db2 4549f64 b6b5db2 b33e052 b6b5db2 | 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 | import string
import random
import gradio as ui
def generate_secret_alphabet(key: str) -> str:
"""Generates a deterministic shuffled alphabet based on the provided key."""
standard_alphabet = list(string.ascii_uppercase)
# Using random.Random with a seed ensures determinism across runs
seeded_random = random.Random(key)
seeded_random.shuffle(standard_alphabet)
return "".join(standard_alphabet)
def validate_inputs(key: str, text: str):
"""Validates that key and text are not empty or just whitespace."""
if not key.strip():
raise ui.Error("Key cannot be empty! Please enter a valid key.")
if not text.strip():
raise ui.Error("Text cannot be empty! Please enter some text.")
def encrypt_text(key: str, plain_text: str):
validate_inputs(key, plain_text)
secret_alphabet = generate_secret_alphabet(key)
standard_alphabet = string.ascii_uppercase
# Create mapping dictionaries for fast lookup
upper_map = {src: dst for src, dst in zip(standard_alphabet, secret_alphabet)}
lower_map = {src.lower(): dst.lower() for src, dst in zip(standard_alphabet, secret_alphabet)}
encrypted_chars = []
for char in plain_text:
if char.isupper():
encrypted_chars.append(upper_map.get(char, char))
elif char.islower():
encrypted_chars.append(lower_map.get(char, char))
else:
encrypted_chars.append(char)
# Format alphabet display for the user
alphabet_display = f"Standard: {standard_alphabet}\nSecret: {secret_alphabet}"
return "".join(encrypted_chars), alphabet_display
def decrypt_text(key: str, cipher_text: str):
validate_inputs(key, cipher_text)
secret_alphabet = generate_secret_alphabet(key)
standard_alphabet = string.ascii_uppercase
# Reverse mapping for decryption
upper_map = {src: dst for src, dst in zip(secret_alphabet, standard_alphabet)}
lower_map = {src.lower(): dst.lower() for src, dst in zip(secret_alphabet, standard_alphabet)}
decrypted_chars = []
for char in cipher_text:
if char.isupper():
decrypted_chars.append(upper_map.get(char, char))
elif char.islower():
decrypted_chars.append(lower_map.get(char, char))
else:
decrypted_chars.append(char)
alphabet_display = f"Standard: {standard_alphabet}\nSecret: {secret_alphabet}"
return "".join(decrypted_chars), alphabet_display
# Build the Gradio Interface
with ui.Blocks(title="Cipherer") as demo:
ui.Markdown("# ๐ Cipherer")
ui.Markdown(
"Encrypt and decrypt text using a deterministic, key-based substitution cipher. "
"The same key will always generate the exact same secret alphabet mapping."
)
with ui.Tabs():
# --- ENCRYPT TAB ---
with ui.TabItem("โ๏ธ Encrypt"):
with ui.Row():
with ui.Column():
encrypt_key = ui.Textbox(
label="Secret Key",
placeholder="e.g., TOMATO",
max_lines=1
)
plain_input = ui.Textbox(
label="Plain Text",
placeholder="Enter text to encrypt here...",
lines=5
)
encrypt_btn = ui.Button("Encrypt Text", variant="primary")
with ui.Column():
encrypt_output = ui.Textbox(
label="Encrypted Output",
interactive=False,
lines=5
)
encrypt_mapping = ui.Textbox(
label="Generated Alphabet Mapping",
interactive=False,
lines=2
)
encrypt_btn.click(
fn=encrypt_text,
inputs=[encrypt_key, plain_input],
outputs=[encrypt_output, encrypt_mapping]
)
# --- DECRYPT TAB ---
with ui.TabItem("๐ Decrypt"):
with ui.Row():
with ui.Column():
decrypt_key = ui.Textbox(
label="Secret Key",
placeholder="e.g., TOMATO",
max_lines=1
)
cipher_input = ui.Textbox(
label="Cipher Text",
placeholder="Enter text to decrypt here...",
lines=5
)
decrypt_btn = ui.Button("Decrypt Text", variant="primary")
with ui.Column():
decrypt_output = ui.Textbox(
label="Decrypted Output",
interactive=False,
lines=5
)
decrypt_mapping = ui.Textbox(
label="Generated Alphabet Mapping",
interactive=False,
lines=2
)
decrypt_btn.click(
fn=decrypt_text,
inputs=[decrypt_key, cipher_input],
outputs=[decrypt_output, decrypt_mapping]
)
# --- FOOTER CREDITS ---
ui.HTML(
"""
<div style="text-align: center; margin-top: 25px;">
<a href="https://www.instagram.com/kosmos.cpp" target="_blank" style="text-decoration: none; color: #E1306C; font-weight: bold; font-size: 15px;">
Follow Me ig@kosmos.cpp
</a>
</div>
"""
)
if __name__ == "__main__":
demo.launch(theme=ui.themes.Soft())
|