GenCon - Contraseñas

Python
"""
Generador de Contraseñas Seguras
=================================
Características:
- Generación aleatoria con parámetros configurables
- Análisis de fortaleza basado en entropía
- Verificación contra patrones comunes
- Sugerencias de mejora
"""

import random
import string
import math
import re


class GeneradorContraseñas:
    """GenCon - Genera y analiza contraseñas seguras."""
    
    # Patrones comunes débiles
    PATRONES_DEBILES = [
        r'(.)\1{2,}',           # Caracteres repetidos (aaa, 111)
        r'(012|123|234|345|456|567|678|789)',  # Secuencias numéricas
        r'(abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz)',  # Secuencias alfabéticas
        r'(qwerty|asdf|zxcv|password|123456|admin)',  # Patrones comunes
    ]
    
    def __init__(self):
        self.caracteres_minusculas = string.ascii_lowercase
        self.caracteres_mayusculas = string.ascii_uppercase
        self.caracteres_digitos = string.digits
        self.caracteres_especiales = "!@#$%^&*()_+-=[]{}|;:,.<>?"
    
    def generar_contraseña(self, longitud: int = 16, 
                          usar_mayusculas: bool = True,
                          usar_digitos: bool = True,
                          usar_especiales: bool = True,
                          evitar_ambiguos: bool = True) -> str:
        """
        Genera una contraseña aleatoria segura.
        
        Args:
            longitud: Longitud deseada de la contraseña
            usar_mayusculas: Incluir letras mayúsculas
            usar_digitos: Incluir dígitos
            usar_especiales: Incluir caracteres especiales
            evitar_ambiguos: Evitar caracteres ambiguos (0, O, l, 1, I)
        
        Returns:
            Contraseña generada
        """
        conjunto_caracteres = self.caracteres_minusculas
        
        if usar_mayusculas:
            conjunto_caracteres += self.caracteres_mayusculas
        
        if usar_digitos:
            conjunto_caracteres += self.caracteres_digitos
        
        if usar_especiales:
            conjunto_caracteres += self.caracteres_especiales
        
        # Eliminar caracteres ambiguos si se solicita
        if evitar_ambiguos:
            ambiguos = "0Ool1I|{}[]"
            conjunto_caracteres = ''.join(c for c in conjunto_caracteres if c not in ambiguos)
        
        # Asegurar al menos un carácter de cada tipo seleccionado
        contraseña = []
        
        if usar_mayusculas:
            contraseña.append(random.choice(self.caracteres_mayusculas))
        
        if usar_digitos:
            contraseña.append(random.choice(self.caracteres_digitos))
        
        if usar_especiales:
            contraseña.append(random.choice(self.caracteres_especiales))
        
        # Rellenar el resto aleatoriamente
        restante = longitud - len(contraseña)
        for _ in range(restante):
            contraseña.append(random.choice(conjunto_caracteres))
        
        # Mezclar la contraseña
        random.shuffle(contraseña)
        
        return ''.join(contraseña)
    
    def calcular_entropia(self, contraseña: str) -> float:
        """
        Calcula la entropía de la contraseña en bits.
        
        Fórmula: E = L * log2(R)
        Donde L = longitud, R = tamaño del conjunto de caracteres
        """
        if not contraseña:
            return 0
        
        # Determinar el tamaño del conjunto de caracteres usado
        tiene_minusculas = any(c in self.caracteres_minusculas for c in contraseña)
        tiene_mayusculas = any(c in self.caracteres_mayusculas for c in contraseña)
        tiene_digitos = any(c in self.caracteres_digitos for c in contraseña)
        tiene_especiales = any(c in self.caracteres_especiales for c in contraseña)
        
        tamaño_conjunto = 0
        if tiene_minusculas:
            tamaño_conjunto += 26
        if tiene_mayusculas:
            tamaño_conjunto += 26
        if tiene_digitos:
            tamaño_conjunto += 10
        if tiene_especiales:
            tamaño_conjunto += len(self.caracteres_especiales)
        
        if tamaño_conjunto == 0:
            return 0
        
        entropia = len(contraseña) * math.log2(tamaño_conjunto)
        return round(entropia, 2)
    
    def verificar_patrones_debiles(self, contraseña: str) -> list:
        """Verifica si la contraseña contiene patrones débiles."""
        patrones_encontrados = []
        
        for patron in self.PATRONES_DEBILES:
            if re.search(patron, contraseña, re.IGNORECASE):
                patrones_encontrados.append(patron)
        
        return patrones_encontrados
    
    def analizar_fortaleza(self, contraseña: str) -> dict:
        """
        Analiza la fortaleza de una contraseña.
        
        Returns:
            Diccionario con métricas de seguridad
        """
        longitud = len(contraseña)
        entropia = self.calcular_entropia(contraseña)
        patrones_debiles = self.verificar_patrones_debiles(contraseña)
        
        # Puntuación basada en múltiples factores
        puntuacion = 0
        
        # Longitud (máximo 30 puntos)
        if longitud >= 16:
            puntuacion += 30
        elif longitud >= 12:
            puntuacion += 25
        elif longitud >= 10:
            puntuacion += 20
        elif longitud >= 8:
            puntuacion += 15
        else:
            puntuacion += max(0, longitud * 2)
        
        # Entropía (máximo 30 puntos)
        if entropia >= 80:
            puntuacion += 30
        elif entropia >= 60:
            puntuacion += 25
        elif entropia >= 50:
            puntuacion += 20
        elif entropia >= 40:
            puntuacion += 15
        else:
            puntuacion += max(0, int(entropia / 2))
        
        # Diversidad de caracteres (máximo 20 puntos)
        tipos_usados = 0
        if any(c in self.caracteres_minusculas for c in contraseña):
            tipos_usados += 1
        if any(c in self.caracteres_mayusculas for c in contraseña):
            tipos_usados += 1
        if any(c in self.caracteres_digitos for c in contraseña):
            tipos_usados += 1
        if any(c in self.caracteres_especiales for c in contraseña):
            tipos_usados += 1
        
        puntuacion += tipos_usados * 5
        
        # Penalización por patrones débiles (máximo -20 puntos)
        penalizacion = len(patrones_debiles) * 10
        puntuacion -= penalizacion
        
        # Normalizar puntuación entre 0-100
        puntuacion = max(0, min(100, puntuacion))
        
        # Determinar nivel de fortaleza
        if puntuacion >= 80:
            nivel = "MUY FUERTE"
        elif puntuacion >= 60:
            nivel = "FUERTE"
        elif puntuacion >= 40:
            nivel = "MODERADA"
        elif puntuacion >= 20:
            nivel = "DÉBIL"
        else:
            nivel = "MUY DÉBIL"
        
        # Generar sugerencias
        sugerencias = []
        if longitud < 12:
            sugerencias.append("Aumenta la longitud a al menos 12 caracteres")
        if tipos_usados < 4:
            sugerencias.append("Usa combinación de mayúsculas, minúsculas, números y símbolos")
        if patrones_debiles:
            sugerencias.append("Evita secuencias repetidas o patrones comunes")
        if entropia < 50:
            sugerencias.append("La entropía es baja, usa más variedad de caracteres")
        
        return {
            "contraseña": contraseña,
            "longitud": longitud,
            "entropia_bits": entropia,
            "tipos_caracteres": tipos_usados,
            "patrones_debiles": len(patrones_debiles),
            "puntuacion": puntuacion,
            "nivel": nivel,
            "sugerencias": sugerencias
        }
    
    def generar_varias(self, cantidad: int = 5, **kwargs) -> list:
        """Genera múltiples contraseñas."""
        return [self.generar_contraseña(**kwargs) for _ in range(cantidad)]


def main():
    """Interfaz principal del generador."""
    generador = GeneradorContraseñas()
    
    print("=" * 60)
    print("GenCon - GENERADOR Y ANALIZADOR DE CONTRASEÑAS SEGURAS")
    print("=" * 60)
    
    while True:
        print("\nOpciones:")
        print("1. Generar contraseña")
        print("2. Analizar contraseña existente")
        print("3. Generar múltiples contraseñas")
        print("4. Salir")
        
        opcion = input("\nSelecciona una opción: ").strip()
        
        if opcion == "1":
            print("\nConfiguración de generación:")
            try:
                longitud = int(input("Longitud (default 16): ").strip() or "16")
            except ValueError:
                longitud = 16
            
            usar_mayusculas = input("¿Usar mayúsculas? (s/n, default s): ").strip().lower() != 'n'
            usar_digitos = input("¿Usar dígitos? (s/n, default s): ").strip().lower() != 'n'
            usar_especiales = input("¿Usar caracteres especiales? (s/n, default s): ").strip().lower() != 'n'
            evitar_ambiguos = input("¿Evitar caracteres ambiguos? (s/n, default s): ").strip().lower() != 'n'
            
            contraseña = generador.generar_contraseña(
                longitud=longitud,
                usar_mayusculas=usar_mayusculas,
                usar_digitos=usar_digitos,
                usar_especiales=usar_especiales,
                evitar_ambiguos=evitar_ambiguos
            )
            
            print(f"\nContraseña generada: {contraseña}")
            
            # Analizar automáticamente
            analisis = generador.analizar_fortaleza(contraseña)
            print(f"Nivel de fortaleza: {analisis['nivel']}")
            print(f"Puntuación: {analisis['puntuacion']}/100")
            print(f"Entropía: {analisis['entropia_bits']} bits")
            
            if analisis['sugerencias']:
                print("\nSugerencias:")
                for sugerencia in analisis['sugerencias']:
                    print(f"  - {sugerencia}")
        
        elif opcion == "2":
            contraseña = input("\nIngresa la contraseña a analizar: ").strip()
            if not contraseña:
                print("Error: La contraseña no puede estar vacía.")
                continue
            
            analisis = generador.analizar_fortaleza(contraseña)
            
            print("\n" + "=" * 60)
            print("ANÁLISIS DE FORTALEZA")
            print("=" * 60)
            print(f"Contraseña: {'*' * len(contraseña)}")
            print(f"Longitud: {analisis['longitud']} caracteres")
            print(f"Entropía: {analisis['entropia_bits']} bits")
            print(f"Tipos de caracteres usados: {analisis['tipos_caracteres']}/4")
            print(f"Patrones débiles detectados: {analisis['patrones_debiles']}")
            print(f"Puntuación: {analisis['puntuacion']}/100")
            print(f"Nivel: {analisis['nivel']}")
            
            if analisis['sugerencias']:
                print("\nSugerencias de mejora:")
                for i, sugerencia in enumerate(analisis['sugerencias'], 1):
                    print(f"  {i}. {sugerencia}")
        
        elif opcion == "3":
            try:
                cantidad = int(input("¿Cuántas contraseñas generar? (default 5): ").strip() or "5")
            except ValueError:
                cantidad = 5
            
            contraseñas = generador.generar_varias(cantidad=cantidad, longitud=16)
            
            print(f"\n{cantidad} contraseñas generadas:")
            print("-" * 40)
            for i, pwd in enumerate(contraseñas, 1):
                print(f"{i}. {pwd}")
        
        elif opcion == "4":
            print("¡Hasta luego!")
            break
        
        else:
            print("Opción inválida.")


if __name__ == "__main__":
    main()
Feedback wanted
juandiegosoto33548Triumphant juandiegosoto33548
Sign in to react
Uploaded Jul 25, 2026

GenCon es un generador de contraseñas seguras de maxima seguridad funciona perfectamente cuando no sabes que contraseña poner a un sitio web, iniciar sesion, etc...

Feedback

Sign in to leave feedback

Published feedback

Robby
InimitableRobby
Updated Jul 25, 2026

Me encanta cómo has incluido la verificación de patrones débiles en tu generador de contraseñas, es una función muy importante para mejorar la seguridad, ¡realmente se nota tu esfuerzo en diseñar una herramienta útil!

Juan diego Soto, tu proyecto 'GenCon - Contraseñas' muestra una creatividad genial en la generación de contraseñas y sus análisis, sigue así, ¡tienes grandes ideas que pueden brillar aún más!