mansi14883md/AI-Keystroke-Security-System
1
1import csv2import os3import time4import tkinter as tk5from tkinter import messagebox6from typing import List, Optional7 8 9TARGET_TEXT = "secure123"10DATA_FOLDER = "data"11 12 13def ensure_data_folder() -> None:14 os.makedirs(DATA_FOLDER, exist_ok=True)15 16 17def get_output_file(user_type: str) -> str:18 if user_type == "genuine":19 return os.path.join(DATA_FOLDER, "genuine.csv")20 return os.path.join(DATA_FOLDER, "impostor.csv")21 22 23def create_header() -> List[str]:24 return [f"hold_{index + 1}" for index in range(len(TARGET_TEXT))] + ["label"]25 26 27def initialize_csv(file_path: str) -> None:28 if not os.path.exists(file_path):29 with open(file_path, "w", newline="", encoding="utf-8") as file:30 writer = csv.writer(file)31 writer.writerow(create_header())32 33 34class SampleCaptureWindow:35 def __init__(self, sample_number: int, total_samples: int, parent: tk.Misc | None = None) -> None:36 self.parent = parent37 self.root = tk.Toplevel(parent) if parent is not None else tk.Tk()38 self.root.title("Keystroke Sample Capture")39 self.root.geometry("520x320")40 self.root.resizable(False, False)41 self.root.transient(parent) if parent is not None else None42 self.root.grab_set() if parent is not None else None43 44 self.sample_number = sample_number45 self.total_samples = total_samples46 self.press_times = {}47 self.hold_times: List[float] = []48 self.result: Optional[List[float]] = None49 50 self.build_gui()51 52 def build_gui(self) -> None:53 tk.Label(54 self.root,55 text="Keystroke Data Capture",56 font=("Arial", 16, "bold"),57 pady=10,58 ).pack()59 60 tk.Label(61 self.root,62 text=f"Sample {self.sample_number} of {self.total_samples}",63 font=("Arial", 12),64 ).pack()65 66 tk.Label(67 self.root,68 text=f"Type this text exactly: {TARGET_TEXT}",69 font=("Arial", 13, "bold"),70 pady=10,71 ).pack()72 73 tk.Label(74 self.root,75 text="Type normally and then click Save Sample",76 font=("Arial", 11),77 ).pack()78 79 self.entry = tk.Entry(self.root, font=("Arial", 16), width=25)80 self.entry.pack(pady=20)81 self.entry.focus_set()82 self.entry.bind("<KeyPress>", self.on_key_press)83 self.entry.bind("<KeyRelease>", self.on_key_release)84 85 tk.Button(86 self.root,87 text="Save Sample",88 command=self.save_sample,89 font=("Arial", 12, "bold"),90 width=18,91 bg="#2e8b57",92 fg="white",93 ).pack(pady=8)94 95 tk.Button(96 self.root,97 text="Clear",98 command=self.clear_entry,99 font=("Arial", 11),100 width=18,101 ).pack()102 103 self.status_label = tk.Label(self.root, text="", font=("Arial", 11), fg="blue", pady=15)104 self.status_label.pack()105 106 def on_key_press(self, event) -> None:107 if event.keysym in {"BackSpace", "Delete"}:108 self.clear_entry()109 return110 self.press_times[event.keysym] = time.time()111 112 def on_key_release(self, event) -> None:113 if event.keysym not in self.press_times:114 return115 116 hold_time = time.time() - self.press_times[event.keysym]117 self.hold_times.append(round(hold_time, 6))118 119 def clear_entry(self) -> None:120 self.entry.delete(0, tk.END)121 self.press_times.clear()122 self.hold_times.clear()123 self.status_label.config(text="Entry cleared. Type again.")124 125 def save_sample(self) -> None:126 typed_text = self.entry.get()127 if typed_text != TARGET_TEXT:128 messagebox.showwarning("Invalid Text", "Please type the fixed text exactly as shown.")129 self.clear_entry()130 return131 132 if len(self.hold_times) < len(TARGET_TEXT):133 messagebox.showwarning("Incomplete Sample", "Please type the full text normally without skipping keys.")134 self.clear_entry()135 return136 137 self.result = self.hold_times[: len(TARGET_TEXT)]138 self.root.destroy()139 140 def run(self) -> Optional[List[float]]:141 if self.parent is not None:142 self.root.wait_window()143 else:144 self.root.mainloop()145 return self.result146 147 148def append_sample(file_path: str, hold_times: List[float], label: int) -> None:149 with open(file_path, "a", newline="", encoding="utf-8") as file:150 writer = csv.writer(file)151 writer.writerow(hold_times + [label])152 153 154def main() -> None:155 ensure_data_folder()156 157 print("AI-Based Secure Authentication System Using Keystroke Dynamics")158 print("Dataset Collection Tool")159 print("-" * 60)160 print("1. Genuine User Data")161 print("2. Impostor Data")162 163 choice = input("Enter your choice (1 or 2): ").strip()164 if choice == "1":165 user_type = "genuine"166 label = 1167 elif choice == "2":168 user_type = "impostor"169 label = 0170 else:171 print("Invalid choice. Run the program again.")172 return173 174 try:175 sample_count = int(input("How many samples do you want to record? ").strip())176 except ValueError:177 print("Please enter a valid number.")178 return179 180 file_path = get_output_file(user_type)181 initialize_csv(file_path)182 183 saved_samples = 0184 while saved_samples < sample_count:185 capture_window = SampleCaptureWindow(saved_samples + 1, sample_count)186 sample = capture_window.run()187 if sample is None:188 print("Sample window closed before saving. Stopping capture.")189 break190 191 append_sample(file_path, sample, label)192 saved_samples += 1193 print(f"Sample {saved_samples} saved successfully.")194 195 print(f"\nSaved {saved_samples} sample(s) in: {file_path}")196 if saved_samples > 0:197 print("Next step: run train_model.py")198 199 200if __name__ == "__main__":201 main()202 