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())