import tkinter as tk from tkinter import filedialog, ttk, messagebox import re from typing import Tuple, List from collections import Counter class PSADecoder: def __init__(self): # Tabela de decodificação exata do PDF (Table 1) self.decode_table = { 0xCF: '0', 0xCE: '1', 0xCD: '2', 0xCC: '3', 0xCB: '4', 0xCA: '5', 0xC9: '6', 0xC8: '7', 0xC7: '8', 0xC6: '9', 0xBE: 'A', 0xBD: 'B', 0xBC: 'C', 0xBB: 'D', 0xBA: 'E', 0xB9: 'F', 0xB8: 'G', 0xB7: 'H', 0xB6: 'I', 0xB5: 'J', 0xB4: 'K', 0xB3: 'L', 0xB2: 'M', 0xB1: 'N', 0xB0: 'O', 0xAF: 'P', 0xAE: 'Q', 0xAD: 'R', 0xAC: 'S', 0xAB: 'T', 0xAA: 'U', 0xA9: 'V', 0xA8: 'W', 0xA7: 'X', 0xA6: 'Y', 0xA5: 'Z' } def decode_bytes(self, data: bytes) -> str: decoded = '' for byte in data: if byte in self.decode_table: decoded += self.decode_table[byte] else: decoded += ' ' # Substitui caracteres não encontrados na tabela por espaço return decoded class VINPINFinder(tk.Tk): def __init__(self): super().__init__() self.decoder = PSADecoder() self.title("Decodificador BSI PSA - VIN/PIN Finder") self.geometry("800x600") # Criar o frame principal main_frame = ttk.Frame(self, padding="10") main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) # Botão para selecionar arquivo self.select_button = ttk.Button( main_frame, text="Selecionar Arquivo BSI", command=self.select_file ) self.select_button.grid(row=0, column=0, pady=10, sticky=tk.W) self.select_buttonb = ttk.Button(main_frame, text="About", command=self.show_about) self.select_buttonb.grid(row=0, column=1, pady=10, sticky=tk.W) # Label para mostrar o arquivo selecionado self.file_label = ttk.Label(main_frame, text="Nenhum arquivo selecionado") self.file_label.grid(row=1, column=0, pady=5, sticky=tk.W) # Frame para resultados results_frame = ttk.LabelFrame(main_frame, text="Resultados da Decodificação", padding="5") results_frame.grid(row=2, column=0, pady=10, sticky=(tk.W, tk.E, tk.N, tk.S)) # Texto para mostrar resultados self.results_text = tk.Text(results_frame, height=20, width=80) self.results_text.grid(row=0, column=0, pady=5) # Scrollbar para resultados scrollbar = ttk.Scrollbar(results_frame, orient=tk.VERTICAL, command=self.results_text.yview) scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S)) self.results_text.configure(yscrollcommand=scrollbar.set) def validate_vin_occurrences(self, vins: List[str]) -> List[str]: """Valida VINs que aparecem entre 2 e 3 vezes""" counter = Counter(vins) valid_vins = [vin for vin, count in counter.items() if 2 <= count <= 3] return valid_vins def find_isolated_pin(self, decoded_content: str) -> str: """ Procura por um PIN isolado (4 caracteres alfanuméricos com não-alfanuméricos ao redor) Usa lookbehind e lookahead para garantir que o PIN está isolado """ # Padrão modificado: # (?