#!/usr/bin/env python3 import secrets import string import argparse import sys import math # Códigos ANSI para cores no terminal class Color: PURPLE = '\033[95m' CYAN = '\033[96m' DARKCYAN = '\033[36m' BLUE = '\033[94m' GREEN = '\033[92m' YELLOW = '\033[93m' RED = '\033[91m' BOLD = '\033[1m' END = '\033[0m' MAX_OUTPUT_WIDTH = 113 def generate_password(length: int) -> str: """ Gera uma senha segura e aleatória com no máximo 2 caracteres especiais: $ # & !. """ if length < 6: raise ValueError("O comprimento da senha deve ser de pelo menos 6.") base_chars = string.ascii_letters + string.digits special_chars = "$#&!" num_special = secrets.randbelow(3) password_list = [] if num_special > 0: special_indices = secrets.SystemRandom().sample(range(length), num_special) for i in range(length): if i in special_indices: char = secrets.choice(special_chars) else: char = secrets.choice(base_chars) password_list.append(char) else: password_list = [secrets.choice(base_chars) for _ in range(length)] secrets.SystemRandom().shuffle(password_list) return "".join(password_list) def print_formatted_output(passwords: list, password_length: int): """ Imprime a lista de senhas. """ # 1. Calcular o tamanho do bloco (quantas senhas cabem) space_per_password = password_length + 1 block_size = (MAX_OUTPUT_WIDTH - 2) // space_per_password block_size = max(1, block_size) # 2. Impressão do Cabeçalho separator_line = Color.CYAN + "-" * MAX_OUTPUT_WIDTH + Color.END print(Color.BOLD + "\nParâmetros:" + Color.END) print(f" --p, -p {Color.YELLOW}Senhas a serem geradas{Color.END}") print(f" --c, -c {Color.YELLOW}Comprimento de senha{Color.END}\n") print(f"Exemplo:\n {Color.BLUE}password -p 10 -c 25{Color.END}\n") print(separator_line) print() output_lines = [] for i in range(0, len(passwords), block_size): current_block = passwords[i : i + block_size] colored_passwords = [Color.GREEN + p + Color.END for p in current_block] line_content = ' '.join(colored_passwords) output_lines.append(f" {line_content} ") print("\n".join(output_lines)) print() print(separator_line) if __name__ == "__main__": parser = argparse.ArgumentParser(add_help=False) # Quantidade de Senhas: -p e --p parser.add_argument( '-p', '--p', dest='passwords', # Variável interna é 'passwords' type=int, default=10, help=argparse.SUPPRESS ) # Comprimento da Senha: -c e --c parser.add_argument( '-c', '--c', dest='chars', # Variável interna é 'chars' type=int, default=20, help=argparse.SUPPRESS ) args = parser.parse_args() # 2. Validações if args.chars < 6: print(f"{Color.RED}Erro:{Color.END} O comprimento da senha ({args.chars}) deve ser de pelo menos 6 caracteres.", file=sys.stderr) sys.exit(1) if args.passwords <= 0: print(f"{Color.RED}Aviso:{Color.END} A quantidade de senhas deve ser maior que zero. Gerando 1 senha.", file=sys.stderr) args.passwords = 1 # 3. Geração all_passwords = [] for _ in range(args.passwords): password = generate_password(length=args.chars) all_passwords.append(password) # 4. Impressão formatada print_formatted_output(all_passwords, password_length=args.chars)