File size: 4,840 Bytes
2566efa
 
c7ed8c0
2566efa
1c0f80c
c7ed8c0
1c0f80c
 
c7ed8c0
 
 
 
 
f5b626e
c7ed8c0
 
 
 
 
 
 
 
 
 
1c0f80c
 
 
 
 
 
 
c7ed8c0
2566efa
 
 
 
 
c7ed8c0
 
 
 
 
 
 
 
2566efa
 
 
c7ed8c0
2566efa
 
1c0f80c
2566efa
f5b626e
401162a
f5b626e
 
 
 
 
2566efa
c12d457
 
1c0f80c
282e341
97a7eb0
f5b626e
97a7eb0
 
 
 
 
 
 
 
 
 
1c0f80c
f5b626e
1c0f80c
 
c7ed8c0
282e341
2566efa
cd6ec40
1c0f80c
1c427f0
2566efa
cd6ec40
2566efa
 
97a7eb0
1c0f80c
97a7eb0
 
 
 
 
1c0f80c
97a7eb0
f5b626e
2566efa
c7ed8c0
 
 
2566efa
c7ed8c0
2566efa
c7ed8c0
f5b626e
 
c12d457
1c0f80c
c7ed8c0
 
401162a
1c0f80c
2566efa
 
1c0f80c
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
import gradio as gr
import re
import math

# 1. Crack Time Logic
def estimate_crack_time(password):
    if not password:
        return "0 seconds"
    L = 0
    if re.search(r"[a-z]", password): L += 26
    if re.search(r"[A-Z]", password): L += 26
    if re.search(r"\d", password): L += 10
    if re.search(r"[!@#$%^&*(),.?\":{}|<>]", password): L += 32
    if L == 0: L = 1 
    combinations = math.pow(L, len(password))
    seconds = combinations / 10_000_000_000
    if seconds < 1: return "Instantly ⚑"
    if seconds < 60: return f"{int(seconds)} seconds"
    if seconds < 3600: return f"{int(seconds/60)} minutes"
    if seconds < 86400: return f"{int(seconds/3600)} hours"
    if seconds < 31536000: return f"{int(seconds/86400)} days"
    if seconds < 31536000000: return f"{int(seconds/31536000)} years"
    return "Centuries 🏰"

def analyze_password(password):
    if not password:
        return render_checklist(""), 0, "0 seconds"
    checklist_html, strength = render_checklist(password)
    crack_time = estimate_crack_time(password)
    return checklist_html, strength, crack_time

def render_checklist(password):
    has_upper = re.search(r"[A-Z]", password)
    has_lower = re.search(r"[a-z]", password)
    has_num = re.search(r"\d", password)
    has_spec = re.search(r"[!@#$%^&*(),.?\":{}|<>]", password)
    has_len = len(password) >= 8
    def get_label(is_met, text):
        color = "#28a745" if is_met else "#dc3545"
        symbol = "βœ…" if is_met else "❌"
        return f"<b style='color:{color};'>{symbol} {text}</b>"
    html = f"""
    <div style="border: 1px solid #888; padding: 15px; border-radius: 10px; background-color: rgba(128,128,128,0.05);">
        <p><b>Requirements:</b></p>
        {get_label(has_len, "8+ Chars")} | {get_label(has_upper, "Upper")} | {get_label(has_lower, "Lower")} | {get_label(has_num, "Number")} | {get_label(has_spec, "Special")}
    </div>
    """
    score = sum([bool(has_len), bool(has_upper), bool(has_lower), bool(has_num), bool(has_spec)])
    return html, (score / 5) * 100

def toggle_visibility(is_visible):
    # If currently visible, hide it (show πŸ‘οΈ). If hidden, show it (show πŸ™ˆ)
    new_type = "text" if is_visible else "password"
    new_icon = "πŸ™ˆ" if is_visible else "πŸ‘οΈ"
    return gr.Textbox(type=new_type), new_icon, not is_visible

def toggle_dark_mode(current_is_dark):
    new_state = not current_is_dark
    new_label = "β˜€οΈ Light Mode" if new_state else "πŸŒ™ Dark Mode"
    return new_label, new_state

toggle_dark_js = """() => { document.body.classList.toggle('dark'); }"""

# CSS to force the button inside the input bar area
custom_css = """
.input-container { position: relative; }
.eye-btn { 
    position: absolute !important;
    right: 10px !important;
    bottom: 8px !important;
    width: 35px !important;
    min-width: 35px !important;
    height: 30px !important;
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    z-index: 10;
    cursor: pointer;
}
.eye-btn:hover { transform: scale(1.1); }
.gradio-container { max-width: 800px; margin: auto; }
.time-display { font-size: 1.5em; font-weight: bold; color: #ff4b4b; }
"""

with gr.Blocks() as demo:
    gr.Markdown("# πŸ›‘οΈ SecurePass Pro Analyzer")
    gr.Markdown("### Developed by Hassan Naseer", elem_classes="brand-subtitle")
    visible_state = gr.State(True)
    dark_state = gr.State(False)

    with gr.Row():
        with gr.Column(scale=4, elem_classes="input-container"):
            # The input field
            pass_input = gr.Textbox(
                label="Enter Password", 
                type="password", 
                placeholder="Type here...",
            )
            # The small eye icon positioned absolutely
            show_btn = gr.Button("πŸ‘οΈ", elem_classes="eye-btn")
        
        with gr.Column(scale=2):
            strength_meter = gr.Slider(label="Strength (%)", interactive=False)
            gr.Markdown("### πŸ•’ Estimated Crack Time:")
            time_output = gr.Markdown("0 seconds", elem_classes="time-display")

    checklist_area = gr.HTML(value=render_checklist("")[0])

    with gr.Row():
        dark_btn = gr.Button("πŸŒ™ Dark Mode", variant="secondary")
        reset_btn = gr.Button("πŸ—‘οΈ Clear", variant="stop")

    # Handlers
    pass_input.change(analyze_password, pass_input, [checklist_area, strength_meter, time_output])
    show_btn.click(toggle_visibility, [visible_state], [pass_input, show_btn, visible_state])
    dark_btn.click(toggle_dark_mode, inputs=[dark_state], outputs=[dark_btn, dark_state], js=toggle_dark_js)
    reset_btn.click(lambda: ["", render_checklist("")[0], 0, "0 seconds"], None, [pass_input, checklist_area, strength_meter, time_output])

if __name__ == "__main__":
    demo.launch(css=custom_css)