Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>SecurePass Generator</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .password-strength-bar { | |
| height: 8px; | |
| transition: all 0.3s ease; | |
| } | |
| @keyframes pulse { | |
| 0% { transform: scale(1); } | |
| 50% { transform: scale(1.05); } | |
| 100% { transform: scale(1); } | |
| } | |
| .glow { | |
| box-shadow: 0 0 15px rgba(59, 130, 246, 0.6); | |
| animation: pulse 2s infinite; | |
| } | |
| .copy-btn:hover i { | |
| transform: rotate(-30deg); | |
| transition: transform 0.3s ease; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-900 min-h-screen flex flex-col items-center justify-center p-4"> | |
| <div class="max-w-md w-full bg-gray-800 rounded-xl shadow-2xl overflow-hidden border border-gray-700"> | |
| <div class="p-6"> | |
| <div class="flex items-center justify-between mb-6"> | |
| <h1 class="text-2xl font-bold text-white flex items-center"> | |
| <i class="fas fa-lock text-blue-400 mr-3"></i> | |
| SecurePass Generator | |
| </h1> | |
| <span class="bg-blue-900 text-blue-200 px-3 py-1 rounded-full text-xs font-semibold">beta</span> | |
| </div> | |
| <div class="relative mb-6"> | |
| <div class="flex items-stretch"> | |
| <input | |
| id="password-output" | |
| type="text" | |
| readonly | |
| class="w-full px-4 py-3 rounded-l-lg bg-gray-700 text-white font-mono focus:outline-none focus:ring-2 focus:ring-blue-500 truncate" | |
| placeholder="Your password will appear here" | |
| > | |
| <button | |
| id="copy-btn" | |
| class="copy-btn bg-blue-600 hover:bg-blue-500 px-4 rounded-r-lg transition-all duration-200 flex items-center justify-center" | |
| title="Copy to clipboard" | |
| > | |
| <i class="fas fa-copy text-white"></i> | |
| </button> | |
| </div> | |
| <div class="flex items-center mt-2"> | |
| <div id="password-strength-bar" class="password-strength-bar w-full rounded-full bg-gray-600"></div> | |
| <span id="password-strength-text" class="ml-3 text-xs font-semibold text-gray-400">Weak</span> | |
| </div> | |
| </div> | |
| <div class="space-y-4"> | |
| <div class="flex items-center justify-between"> | |
| <label for="password-length" class="text-gray-300 font-medium">Length</label> | |
| <div class="flex items-center"> | |
| <input | |
| type="range" | |
| id="password-length" | |
| min="6" | |
| max="32" | |
| value="12" | |
| class="w-32 mr-4 accent-blue-500" | |
| > | |
| <span id="length-value" class="w-8 text-right font-mono font-bold text-white">12</span> | |
| </div> | |
| </div> | |
| <div class="flex items-center justify-between"> | |
| <label for="uppercase" class="text-gray-300 font-medium">Uppercase (ABC)</label> | |
| <div class="relative inline-block w-10 mr-2 align-middle select-none"> | |
| <input | |
| type="checkbox" | |
| id="uppercase" | |
| checked | |
| class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer" | |
| > | |
| <label for="uppercase" class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"></label> | |
| </div> | |
| </div> | |
| <div class="flex items-center justify-between"> | |
| <label for="lowercase" class="text-gray-300 font-medium">Lowercase (abc)</label> | |
| <div class="relative inline-block w-10 mr-2 align-middle select-none"> | |
| <input | |
| type="checkbox" | |
| id="lowercase" | |
| checked | |
| class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer" | |
| > | |
| <label for="lowercase" class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"></label> | |
| </div> | |
| </div> | |
| <div class="flex items-center justify-between"> | |
| <label for="numbers" class="text-gray-300 font-medium">Numbers (123)</label> | |
| <div class="relative inline-block w-10 mr-2 align-middle select-none"> | |
| <input | |
| type="checkbox" | |
| id="numbers" | |
| checked | |
| class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer" | |
| > | |
| <label for="numbers" class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"></label> | |
| </div> | |
| </div> | |
| <div class="flex items-center justify-between"> | |
| <label for="symbols" class="text-gray-300 font-medium">Symbols (!@#)</label> | |
| <div class="relative inline-block w-10 mr-2 align-middle select-none"> | |
| <input | |
| type="checkbox" | |
| id="symbols" | |
| class="toggle-checkbox absolute block w-6 h-6 rounded-full bg-white border-4 appearance-none cursor-pointer" | |
| > | |
| <label for="symbols" class="toggle-label block overflow-hidden h-6 rounded-full bg-gray-300 cursor-pointer"></label> | |
| </div> | |
| </div> | |
| </div> | |
| <button | |
| id="generate-btn" | |
| class="w-full mt-8 bg-blue-600 hover:bg-blue-500 text-white py-3 px-4 rounded-lg font-bold transition-all duration-200 flex items-center justify-center glow" | |
| > | |
| <i class="fas fa-key mr-2"></i> | |
| Generate Password | |
| </button> | |
| <div class="mt-6 flex justify-between items-center"> | |
| <span class="text-xs text-gray-400"> | |
| Passwords are generated in your browser and never stored | |
| </span> | |
| <button id="history-btn" class="text-blue-400 hover:text-blue-300 text-sm font-medium"> | |
| <i class="fas fa-history mr-1"></i> | |
| History | |
| </button> | |
| </div> | |
| </div> | |
| <div id="history-panel" class="hidden bg-gray-700 border-t border-gray-600 max-h-60 overflow-y-auto"> | |
| <div class="p-4"> | |
| <div class="flex items-center justify-between mb-3"> | |
| <h3 class="text-white font-medium">Password History</h3> | |
| <button id="clear-history" class="text-red-400 hover:text-red-300 text-sm"> | |
| <i class="fas fa-trash mr-1"></i> | |
| Clear | |
| </button> | |
| </div> | |
| <ul id="history-list" class="space-y-2"> | |
| <!-- History items will be added here --> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // DOM Elements | |
| const passwordOutput = document.getElementById('password-output'); | |
| const generateBtn = document.getElementById('generate-btn'); | |
| const copyBtn = document.getElementById('copy-btn'); | |
| const passwordLength = document.getElementById('password-length'); | |
| const lengthValue = document.getElementById('length-value'); | |
| const uppercaseCB = document.getElementById('uppercase'); | |
| const lowercaseCB = document.getElementById('lowercase'); | |
| const numbersCB = document.getElementById('numbers'); | |
| const symbolsCB = document.getElementById('symbols'); | |
| const passwordStrengthBar = document.getElementById('password-strength-bar'); | |
| const passwordStrengthText = document.getElementById('password-strength-text'); | |
| const historyBtn = document.getElementById('history-btn'); | |
| const historyPanel = document.getElementById('history-panel'); | |
| const historyList = document.getElementById('history-list'); | |
| const clearHistoryBtn = document.getElementById('clear-history'); | |
| // Character sets | |
| const characterSets = { | |
| uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', | |
| lowercase: 'abcdefghijklmnopqrstuvwxyz', | |
| numbers: '0123456789', | |
| symbols: '!@#$%^&*()_+~`|}{[]:;?><,./-=' | |
| }; | |
| // Password history array | |
| let passwordHistory = JSON.parse(localStorage.getItem('passwordHistory')) || []; | |
| // Update length value display | |
| passwordLength.addEventListener('input', function() { | |
| lengthValue.textContent = this.value; | |
| }); | |
| // Generate password function | |
| function generatePassword() { | |
| const length = parseInt(passwordLength.value); | |
| const hasUppercase = uppercaseCB.checked; | |
| const hasLowercase = lowercaseCB.checked; | |
| const hasNumbers = numbersCB.checked; | |
| const hasSymbols = symbolsCB.checked; | |
| // Validate at least one character set is selected | |
| if (!hasUppercase && !hasLowercase && !hasNumbers && !hasSymbols) { | |
| passwordOutput.value = 'Select at least one option'; | |
| passwordOutput.classList.add('text-red-400'); | |
| return; | |
| } else { | |
| passwordOutput.classList.remove('text-red-400'); | |
| } | |
| // Build character pool | |
| let charPool = ''; | |
| if (hasUppercase) charPool += characterSets.uppercase; | |
| if (hasLowercase) charPool += characterSets.lowercase; | |
| if (hasNumbers) charPool += characterSets.numbers; | |
| if (hasSymbols) charPool += characterSets.symbols; | |
| // Generate password | |
| let password = ''; | |
| for (let i = 0; i < length; i++) { | |
| const randomIndex = Math.floor(Math.random() * charPool.length); | |
| password += charPool[randomIndex]; | |
| } | |
| // Display and save password | |
| passwordOutput.value = password; | |
| updatePasswordStrength(password); | |
| addToHistory(password); | |
| } | |
| // Copy password to clipboard | |
| copyBtn.addEventListener('click', function() { | |
| if (!passwordOutput.value) return; | |
| navigator.clipboard.writeText(passwordOutput.value).then(() => { | |
| const originalContent = copyBtn.innerHTML; | |
| copyBtn.innerHTML = '<i class="fas fa-check text-white"></i>'; | |
| copyBtn.classList.add('bg-green-500'); | |
| copyBtn.classList.remove('bg-blue-600'); | |
| setTimeout(() => { | |
| copyBtn.innerHTML = originalContent; | |
| copyBtn.classList.add('bg-blue-600'); | |
| copyBtn.classList.remove('bg-green-500'); | |
| }, 2000); | |
| }); | |
| }); | |
| // Update password strength indicator | |
| function updatePasswordStrength(password) { | |
| let strength = 0; | |
| // Length score | |
| strength += Math.min(password.length / 8, 3); | |
| // Character diversity score | |
| if (/[A-Z]/.test(password)) strength += 1; | |
| if (/[a-z]/.test(password)) strength += 1; | |
| if (/[0-9]/.test(password)) strength += 1; | |
| if (/[^A-Za-z0-9]/.test(password)) strength += 1; | |
| // Normalize to 0-1 range | |
| strength = Math.min(strength / 5, 1); | |
| // Update UI | |
| const strengthPercent = Math.round(strength * 100); | |
| if ( | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=openaitrend/password-generator" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |