PASO 3: Código generado para Segurito v0.1

Copia este código y pégalo en Sublime Text. Guárdalo como segurito.html y luego ábrelo en el navegador.

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Generador de Contraseñas Seguras</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      background-color: #f4f4f9;
      margin: 0;
      padding: 0;
    }
    .container {
      width: 90%;
      max-width: 600px;
      margin: 50px auto;
      background-color: #fff;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
    }
    h1 {
      text-align: center;
      color: #333;
    }
    .form-group {
      margin-bottom: 15px;
    }
    .form-group label {
      display: block;
      font-weight: bold;
    }
    .form-group input[type="range"], .form-group select {
      width: 100%;
    }
    .form-group input[type="checkbox"] {
      margin-right: 8px;
    }
    .form-group button {
      width: 100%;
      padding: 10px;
      background-color: #007BFF;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
    }
    .form-group button:hover {
      background-color: #0056b3;
    }
    .password-output {
      margin-top: 20px;
      text-align: center;
    }
    .password-output p {
      font-size: 18px;
      font-weight: bold;
    }
    .strength {
      margin-top: 10px;
      font-weight: normal;
    }
  </style>
</head>
<body>

<div class="container">
  <h1>Generador de Contraseñas Seguras</h1>

  <!-- Formulario de personalización -->
  <div class="form-group">
    <label for="length">Longitud de la contraseña (número de palabras):</label>
    <input type="range" id="length" min="4" max="12" value="6">
    <p>Longitud: <span id="length-value">6</span> palabras</p>
  </div>

  <div class="form-group">
    <label for="special">Incluir caracteres especiales (@, #, $, etc.):</label>
    <input type="checkbox" id="special">
  </div>

  <div class="form-group">
    <label for="numbers">Incluir números:</label>
    <input type="checkbox" id="numbers">
  </div>

  <div class="form-group">
    <label for="uppercase">Incluir mayúsculas:</label>
    <input type="checkbox" id="uppercase">
  </div>

  <div class="form-group">
    <button id="generate">Generar Contraseña</button>
  </div>

  <!-- Mostrar contraseñas generadas -->
  <div class="password-output">
    <p id="generated-password">Esperando a generar contraseña...</p>
    <p id="password-strength" class="strength">Fortaleza: No evaluada</p>
  </div>
</div>

<script>
  const spanishWords = [
    'sol', 'luna', 'cielo', 'río', 'montaña', 'viento', 'flor', 'luz', 'cielo', 'estrella', 'bosque', 'mar',
    'ciudad', 'lago', 'nube', 'agua', 'fuego', 'piedra', 'árbol', 'flor', 'puente', 'camino', 'libertad', 'paz'
  ];

  const lengthInput = document.getElementById('length');
  const specialInput = document.getElementById('special');
  const numbersInput = document.getElementById('numbers');
  const uppercaseInput = document.getElementById('uppercase');
  const generateButton = document.getElementById('generate');
  const generatedPasswordEl = document.getElementById('generated-password');
  const passwordStrengthEl = document.getElementById('password-strength');
  const lengthValueEl = document.getElementById('length-value');

  // Función para generar una pass-phrase aleatoria
  function generatePassword() {
    const length = lengthInput.value;
    const includeSpecial = specialInput.checked;
    const includeNumbers = numbersInput.checked;
    const includeUppercase = uppercaseInput.checked;

    let password = generatePassPhrase(length);
    if (includeSpecial) {
      password = addSpecialChars(password);
    }
    if (includeNumbers) {
      password = addNumbers(password);
    }
    if (includeUppercase) {
      password = addUppercase(password);
    }

    const strength = evaluateStrength(password);
    generatedPasswordEl.textContent = password;
    passwordStrengthEl.textContent = `Fortaleza: ${strength}`;

    // Almacenamiento temporal en localStorage
    localStorage.setItem('generatedPassword', password);
  }

  // Genera una pass-phrase aleatoria a partir del conjunto de palabras
  function generatePassPhrase(length) {
    let phrase = '';
    for (let i = 0; i < length; i++) {
      const randomWord = spanishWords[Math.floor(Math.random() * spanishWords.length)];
      phrase += randomWord + ' ';
    }
    return phrase.trim();
  }

  // Añadir caracteres especiales aleatorios
  function addSpecialChars(password) {
    const specialChars = ['@', '#', '$', '%', '&', '*', '!', '?'];
    const randomSpecialChar = specialChars[Math.floor(Math.random() * specialChars.length)];
    const position = Math.floor(Math.random() * password.length);
    return password.slice(0, position) + randomSpecialChar + password.slice(position);
  }

  // Añadir números aleatorios
  function addNumbers(password) {
    const randomNum = Math.floor(Math.random() * 10);
    const position = Math.floor(Math.random() * password.length);
    return password.slice(0, position) + randomNum + password.slice(position);
  }

  // Añadir mayúsculas aleatorias
  function addUppercase(password) {
    const randomIndex = Math.floor(Math.random() * password.length);
    return password.slice(0, randomIndex) + password.charAt(randomIndex).toUpperCase() + password.slice(randomIndex + 1);
  }

  // Evaluar la fortaleza de la contraseña
  function evaluateStrength(password) {
    const lengthCriteria = password.length > 20 ? 'Muy segura' : password.length > 15 ? 'Segura' : 'Débil';
    const specialCharCriteria = /[!@#$%^&*()_+{}\[\]:;"'<>,.?\\/-]/.test(password) ? 1 : 0;
    const numberCriteria = /\d/.test(password) ? 1 : 0;
    const uppercaseCriteria = /[A-Z]/.test(password) ? 1 : 0;

    let score = password.length > 15 ? 2 : 0;
    score += specialCharCriteria;
    score += numberCriteria;
    score += uppercaseCriteria;

    if (score >= 4) return 'Muy segura';
    if (score >= 3) return 'Segura';
    return 'Débil';
  }

  // Actualizar el valor de longitud en el HTML
  lengthInput.addEventListener('input', () => {
    lengthValueEl.textContent = lengthInput.value;
  });

  // Generar contraseña al hacer clic en el botón
  generateButton.addEventListener('click', generatePassword);

  // Recuperar la contraseña generada del localStorage
  if (localStorage.getItem('generatedPassword')) {
    generatedPasswordEl.textContent = localStorage.getItem('generatedPassword');
  }
</script>

</body>
</html>

Código alterno generado por DeepSeek

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Generador de Contraseñas Seguras</title>
    <style>
        :root {
            --bg-color: #f5f5f5;
            --text-color: #333;
            --primary-color: #4a6fa5;
            --secondary-color: #6c757d;
            --success-color: #28a745;
            --warning-color: #ffc107;
            --danger-color: #dc3545;
            --card-bg: #fff;
            --border-color: #ddd;
        }

        [data-theme="dark"] {
            --bg-color: #121212;
            --text-color: #f5f5f5;
            --primary-color: #6c8fc7;
            --secondary-color: #5a6268;
            --card-bg: #1e1e1e;
            --border-color: #444;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: var(--bg-color);
            color: var(--text-color);
            margin: 0;
            padding: 20px;
            transition: all 0.3s ease;
        }

        .container {
            max-width: 600px;
            margin: 0 auto;
            padding: 20px;
        }

        .card {
            background-color: var(--card-bg);
            border-radius: 10px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            padding: 25px;
            margin-bottom: 20px;
            border: 1px solid var(--border-color);
        }

        h1 {
            color: var(--primary-color);
            text-align: center;
            margin-bottom: 25px;
        }

        .form-group {
            margin-bottom: 15px;
        }

        label {
            display: block;
            margin-bottom: 5px;
            font-weight: 600;
        }

        select, input[type="range"], input[type="number"], button {
            width: 100%;
            padding: 10px;
            border-radius: 5px;
            border: 1px solid var(--border-color);
            background-color: var(--card-bg);
            color: var(--text-color);
        }

        button {
            background-color: var(--primary-color);
            color: white;
            border: none;
            cursor: pointer;
            font-weight: bold;
            margin-top: 10px;
            transition: background-color 0.3s;
        }

        button:hover {
            background-color: #3a5a80;
        }

        .result-container {
            margin-top: 20px;
            position: relative;
        }

        .password-result {
            font-size: 1.2rem;
            word-break: break-all;
            padding: 15px;
            background-color: rgba(0, 0, 0, 0.05);
            border-radius: 5px;
            border: 1px dashed var(--border-color);
        }

        .strength-meter {
            height: 5px;
            background-color: var(--secondary-color);
            border-radius: 5px;
            margin-top: 10px;
            overflow: hidden;
        }

        .strength-bar {
            height: 100%;
            width: 0%;
            transition: width 0.3s, background-color 0.3s;
        }

        .copy-btn {
            position: absolute;
            right: 10px;
            top: 10px;
            background-color: var(--secondary-color);
            padding: 5px 10px;
            font-size: 0.8rem;
            width: auto;
        }

        .copy-btn:hover {
            background-color: #5a6268;
        }

        .settings-toggle {
            color: var(--primary-color);
            text-decoration: underline;
            cursor: pointer;
            font-size: 0.9rem;
            margin-bottom: 15px;
            display: inline-block;
        }

        .settings-panel {
            display: none;
            margin-top: 15px;
            padding: 15px;
            background-color: rgba(0, 0, 0, 0.05);
            border-radius: 5px;
        }

        .settings-panel.show {
            display: block;
        }

        .toggle-container {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }

        .switch {
            position: relative;
            display: inline-block;
            width: 60px;
            height: 34px;
        }

        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }

        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            transition: .4s;
            border-radius: 34px;
        }

        .slider:before {
            position: absolute;
            content: "";
            height: 26px;
            width: 26px;
            left: 4px;
            bottom: 4px;
            background-color: white;
            transition: .4s;
            border-radius: 50%;
        }

        input:checked + .slider {
            background-color: var(--primary-color);
        }

        input:checked + .slider:before {
            transform: translateX(26px);
        }

        .history-item {
            padding: 10px;
            border-bottom: 1px solid var(--border-color);
            display: flex;
            justify-content: space-between;
        }

        .history-item:last-child {
            border-bottom: none;
        }

        .controls {
            display: flex;
            justify-content: space-between;
            margin-top: 20px;
        }

        .font-size-controls button {
            width: auto;
            padding: 5px 10px;
            margin-right: 5px;
        }

        @media (max-width: 480px) {
            .container {
                padding: 10px;
            }

            .card {
                padding: 15px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="card">
            <h1>Generador de Contraseñas Seguras</h1>

            <div class="form-group">
                <label for="password-type">Tipo de contraseña:</label>
                <select id="password-type">
                    <option value="random">Contraseña aleatoria</option>
                    <option value="phrase">Pass-phrase en español</option>
                </select>
            </div>

            <div id="random-settings">
                <div class="form-group">
                    <label for="length">Longitud: <span id="length-value">12</span> caracteres</label>
                    <input type="range" id="length" min="8" max="64" value="12">
                </div>
            </div>

            <div id="phrase-settings" style="display: none;">
                <div class="form-group">
                    <label for="word-count">Número de palabras: <span id="word-count-value">4</span></label>
                    <input type="range" id="word-count" min="3" max="8" value="4">
                </div>
            </div>

            <span class="settings-toggle" id="toggle-settings">Mostrar opciones avanzadas</span>

            <div class="settings-panel" id="advanced-settings">
                <div class="form-group">
                    <label>
                        <input type="checkbox" id="uppercase" checked>
                        Incluir mayúsculas
                    </label>
                </div>

                <div class="form-group">
                    <label>
                        <input type="checkbox" id="numbers" checked>
                        Incluir números
                    </label>
                </div>

                <div class="form-group">
                    <label>
                        <input type="checkbox" id="symbols" checked>
                        Incluir símbolos
                    </label>
                </div>

                <div class="form-group">
                    <label>
                        <input type="checkbox" id="avoid-ambiguous">
                        Evitar caracteres ambiguos (l,1,0,O)
                    </label>
                </div>
            </div>

            <button id="generate-btn">Generar Contraseña</button>

            <div class="result-container">
                <div class="password-result" id="password-result">Tu contraseña aparecerá aquí...</div>
                <button class="copy-btn" id="copy-btn">Copiar</button>

                <div class="strength-meter">
                    <div class="strength-bar" id="strength-bar"></div>
                </div>
                <div id="strength-text" style="text-align: center; margin-top: 5px;"></div>
            </div>
        </div>

        <div class="card">
            <h2>Historial</h2>
            <div id="password-history"></div>
            <div class="controls">
                <div class="font-size-controls">
                    <button id="font-small">A-</button>
                    <button id="font-medium">A</button>
                    <button id="font-large">A+</button>
                </div>
                <button id="clear-history">Limpiar historial</button>
            </div>
        </div>

        <div class="toggle-container">
            <span>Modo oscuro</span>
            <label class="switch">
                <input type="checkbox" id="theme-toggle">
                <span class="slider"></span>
            </label>
        </div>
    </div>

    <script>
        // Palabras en español para pass-phrases
        const spanishWords = [
            'casa', 'perro', 'gato', 'sol', 'luna', 'árbol', 'agua', 'fuego', 'tierra', 'aire',
            'libro', 'mano', 'pie', 'ojo', 'boca', 'nariz', 'cielo', 'mar', 'rio', 'montaña',
            'flor', 'hoja', 'piedra', 'arena', 'nube', 'lluvia', 'viento', 'nieve', 'estrella',
            'pan', 'leche', 'queso', 'fruta', 'verde', 'azul', 'rojo', 'amarillo', 'blanco', 'negro',
            'grande', 'pequeño', 'feliz', 'triste', 'rápido', 'lento', 'caliente', 'frío', 'nuevo', 'viejo',
            'uno', 'dos', 'tres', 'cuatro', 'cinco', 'seis', 'siete', 'ocho', 'nueve', 'diez',
            'camino', 'puerta', 'ventana', 'silla', 'mesa', 'cama', 'reloj', 'espejo', 'llave', 'corazón',
            'amigo', 'familia', 'trabajo', 'escuela', 'juego', 'música', 'arte', 'tiempo', 'amor', 'paz'
        ];

        // Símbolos disponibles
        const symbols = '!@#$%^&*()_+-=[]{}|;:,.<>?';

        // Elementos del DOM
        const passwordType = document.getElementById('password-type');
        const randomSettings = document.getElementById('random-settings');
        const phraseSettings = document.getElementById('phrase-settings');
        const lengthInput = document.getElementById('length');
        const lengthValue = document.getElementById('length-value');
        const wordCountInput = document.getElementById('word-count');
        const wordCountValue = document.getElementById('word-count-value');
        const uppercaseCheckbox = document.getElementById('uppercase');
        const numbersCheckbox = document.getElementById('numbers');
        const symbolsCheckbox = document.getElementById('symbols');
        const avoidAmbiguousCheckbox = document.getElementById('avoid-ambiguous');
        const generateBtn = document.getElementById('generate-btn');
        const passwordResult = document.getElementById('password-result');
        const copyBtn = document.getElementById('copy-btn');
        const strengthBar = document.getElementById('strength-bar');
        const strengthText = document.getElementById('strength-text');
        const toggleSettings = document.getElementById('toggle-settings');
        const advancedSettings = document.getElementById('advanced-settings');
        const passwordHistory = document.getElementById('password-history');
        const clearHistoryBtn = document.getElementById('clear-history');
        const fontSmallBtn = document.getElementById('font-small');
        const fontMediumBtn = document.getElementById('font-medium');
        const fontLargeBtn = document.getElementById('font-large');
        const themeToggle = document.getElementById('theme-toggle');

        // Cambiar entre tipos de contraseña
        passwordType.addEventListener('change', function() {
            if (this.value === 'random') {
                randomSettings.style.display = 'block';
                phraseSettings.style.display = 'none';
            } else {
                randomSettings.style.display = 'none';
                phraseSettings.style.display = 'block';
            }
        });

        // Actualizar valores de los sliders
        lengthInput.addEventListener('input', function() {
            lengthValue.textContent = this.value;
        });

        wordCountInput.addEventListener('input', function() {
            wordCountValue.textContent = this.value;
        });

        // Mostrar/ocultar opciones avanzadas
        toggleSettings.addEventListener('click', function() {
            advancedSettings.classList.toggle('show');
            this.textContent = advancedSettings.classList.contains('show') ? 
                'Ocultar opciones avanzadas' : 'Mostrar opciones avanzadas';
        });

        // Generar contraseña
        generateBtn.addEventListener('click', function() {
            let password = '';
            const type = passwordType.value;

            if (type === 'random') {
                password = generateRandomPassword();
            } else {
                password = generatePassPhrase();
            }

            passwordResult.textContent = password;
            checkPasswordStrength(password);
            saveToHistory(password);
        });

        // Generar contraseña aleatoria
        function generateRandomPassword() {
            const length = parseInt(lengthInput.value);
            const includeUppercase = uppercaseCheckbox.checked;
            const includeNumbers = numbersCheckbox.checked;
            const includeSymbols = symbolsCheckbox.checked;
            const avoidAmbiguous = avoidAmbiguousCheckbox.checked;

            let charset = 'abcdefghijklmnopqrstuvwxyz';
            if (includeUppercase) charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
            if (includeNumbers) charset += '0123456789';
            if (includeSymbols) charset += symbols;

            if (avoidAmbiguous) {
                charset = charset.replace(/[l1O0]/g, '');
            }

            let password = '';
            for (let i = 0; i < length; i++) {
                const randomIndex = Math.floor(Math.random() * charset.length);
                password += charset[randomIndex];
            }

            return password;
        }

        // Generar pass-phrase
        function generatePassPhrase() {
            const wordCount = parseInt(wordCountInput.value);
            const includeNumbers = numbersCheckbox.checked;
            const includeSymbols = symbolsCheckbox.checked;

            let phrase = '';

            // Seleccionar palabras aleatorias
            for (let i = 0; i < wordCount; i++) {
                const randomIndex = Math.floor(Math.random() * spanishWords.length);
                phrase += spanishWords[randomIndex];

                if (i < wordCount - 1) {
                    phrase += '-';
                }
            }

            // Añadir número al final si está seleccionado
            if (includeNumbers) {
                const randomNumber = Math.floor(Math.random() * 90) + 10; // Número entre 10-99
                phrase += randomNumber;
            }

            // Añadir símbolo si está seleccionado
            if (includeSymbols) {
                const randomSymbol = symbols[Math.floor(Math.random() * symbols.length)];
                phrase += randomSymbol;
            }

            return phrase;
        }

        // Verificar fortaleza de la contraseña
        function checkPasswordStrength(password) {
            let strength = 0;
            const length = password.length;

            // Longitud
            if (length > 12) strength += 2;
            else if (length > 8) strength += 1;

            // Tipos de caracteres
            if (/[A-Z]/.test(password)) strength += 1;
            if (/[0-9]/.test(password)) strength += 1;
            if (/[^A-Za-z0-9]/.test(password)) strength += 1;

            // Pass-phrases son más fuertes
            if (password.includes('-')) strength += 2;

            // Actualizar UI
            let strengthPercent = 0;
            let strengthLabel = '';
            let strengthColor = '';

            if (strength <= 2) {
                strengthPercent = 33;
                strengthLabel = 'Débil';
                strengthColor = 'var(--danger-color)';
            } else if (strength <= 4) {
                strengthPercent = 66;
                strengthLabel = 'Media';
                strengthColor = 'var(--warning-color)';
            } else {
                strengthPercent = 100;
                strengthLabel = 'Fuerte';
                strengthColor = 'var(--success-color)';
            }

            strengthBar.style.width = strengthPercent + '%';
            strengthBar.style.backgroundColor = strengthColor;
            strengthText.textContent = 'Fortaleza: ' + strengthLabel;
            strengthText.style.color = strengthColor;
        }

        // Copiar al portapapeles
        copyBtn.addEventListener('click', function() {
            const password = passwordResult.textContent;
            if (password && password !== 'Tu contraseña aparecerá aquí...') {
                navigator.clipboard.writeText(password).then(function() {
                    const originalText = copyBtn.textContent;
                    copyBtn.textContent = '¡Copiado!';
                    setTimeout(function() {
                        copyBtn.textContent = originalText;
                    }, 2000);
                });
            }
        });

        // Guardar en historial
        function saveToHistory(password) {
            if (!password || password === 'Tu contraseña aparecerá aquí...') return;

            const historyItem = document.createElement('div');
            historyItem.className = 'history-item';

            const passwordSpan = document.createElement('span');
            passwordSpan.textContent = password;

            const copySpan = document.createElement('span');
            copySpan.textContent = 'Copiar';
            copySpan.style.color = 'var(--primary-color)';
            copySpan.style.cursor = 'pointer';
            copySpan.addEventListener('click', function() {
                navigator.clipboard.writeText(password);
                copySpan.textContent = '¡Copiado!';
                setTimeout(function() {
                    copySpan.textContent = 'Copiar';
                }, 2000);
            });

            historyItem.appendChild(passwordSpan);
            historyItem.appendChild(copySpan);

            // Insertar al principio
            if (passwordHistory.firstChild) {
                passwordHistory.insertBefore(historyItem, passwordHistory.firstChild);
            } else {
                passwordHistory.appendChild(historyItem);
            }

            // Guardar en localStorage
            let history = JSON.parse(localStorage.getItem('passwordHistory') || '[]');
            history.unshift(password);
            if (history.length > 10) history = history.slice(0, 10);
            localStorage.setItem('passwordHistory', JSON.stringify(history));
        }

        // Cargar historial al iniciar
        function loadHistory() {
            const history = JSON.parse(localStorage.getItem('passwordHistory') || '[]');
            history.forEach(password => {
                const historyItem = document.createElement('div');
                historyItem.className = 'history-item';

                const passwordSpan = document.createElement('span');
                passwordSpan.textContent = password;

                const copySpan = document.createElement('span');
                copySpan.textContent = 'Copiar';
                copySpan.style.color = 'var(--primary-color)';
                copySpan.style.cursor = 'pointer';
                copySpan.addEventListener('click', function() {
                    navigator.clipboard.writeText(password);
                    copySpan.textContent = '¡Copiado!';
                    setTimeout(function() {
                        copySpan.textContent = 'Copiar';
                    }, 2000);
                });

                historyItem.appendChild(passwordSpan);
                historyItem.appendChild(copySpan);
                passwordHistory.appendChild(historyItem);
            });
        }

        // Limpiar historial
        clearHistoryBtn.addEventListener('click', function() {
            passwordHistory.innerHTML = '';
            localStorage.removeItem('passwordHistory');
        });

        // Control de tamaño de fuente
        fontSmallBtn.addEventListener('click', function() {
            document.body.style.fontSize = '14px';
        });

        fontMediumBtn.addEventListener('click', function() {
            document.body.style.fontSize = '16px';
        });

        fontLargeBtn.addEventListener('click', function() {
            document.body.style.fontSize = '18px';
        });

        // Tema oscuro/claro
        themeToggle.addEventListener('change', function() {
            if (this.checked) {
                document.documentElement.setAttribute('data-theme', 'dark');
                localStorage.setItem('theme', 'dark');
            } else {
                document.documentElement.setAttribute('data-theme', 'light');
                localStorage.setItem('theme', 'light');
            }
        });

        // Cargar tema guardado
        const savedTheme = localStorage.getItem('theme') || 'light';
        if (savedTheme === 'dark') {
            themeToggle.checked = true;
            document.documentElement.setAttribute('data-theme', 'dark');
        }

        // Cargar historial al iniciar
        loadHistory();

        // Generar una contraseña al cargar la página
        generateBtn.click();
    </script>
</body>
</html>

Vista previa

Zurf.Online