password-generator / index.html
NzService's picture
Add 3 files
c6931eb verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ARCADE PASSWORD GENERATOR</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap">
<script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
<style>
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-5px); }
}
@keyframes flash {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
@keyframes glow {
0% { box-shadow: 0 0 5px #00ff00; }
50% { box-shadow: 0 0 20px #00ff00, 0 0 30px #00ff00; }
100% { box-shadow: 0 0 5px #00ff00; }
}
.blink {
animation: blink 1s step-end infinite;
}
.bounce:hover {
animation: bounce 0.5s ease;
}
.flash {
animation: flash 0.3s ease;
}
.glow {
animation: glow 2s infinite;
}
.pixel-font {
font-family: 'Press Start 2P', cursive;
}
.arcade-btn {
position: relative;
overflow: hidden;
}
.arcade-btn:before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
transition: 0.5s;
}
.arcade-btn:hover:before {
left: 100%;
}
.password-item {
transition: all 0.3s ease;
}
.password-item:hover {
transform: scale(1.02);
box-shadow: 0 0 15px rgba(255, 255, 255, 0.5);
}
.notification {
position: fixed;
top: 20px;
right: 20px;
opacity: 0;
transition: opacity 0.5s;
}
.notification.show {
opacity: 1;
}
</style>
</head>
<body class="bg-black text-white pixel-font min-h-screen flex flex-col items-center p-4">
<!-- Notification -->
<div id="notification" class="notification bg-purple-600 p-4 rounded-lg shadow-lg border-2 border-pink-500 hidden">
<span id="notification-text"></span>
</div>
<!-- Main Container -->
<div class="max-w-3xl w-full border-4 border-purple-600 rounded-lg p-6 bg-gray-900 bg-opacity-90 shadow-xl">
<!-- Header -->
<div class="text-center mb-8">
<h1 class="text-4xl md:text-5xl text-transparent bg-clip-text bg-gradient-to-r from-pink-500 via-blue-400 to-green-400 mb-2">
ARCADE PASSWORD GENERATOR
</h1>
<div class="flex justify-center items-center gap-4">
<div class="bg-blue-900 px-4 py-2 rounded-lg border-2 border-blue-400">
<span class="text-green-400">SAVED: </span>
<span id="saved-count" class="text-yellow-300">00</span>
</div>
<div class="bg-purple-900 px-4 py-2 rounded-lg border-2 border-purple-400">
<span class="text-pink-400">LEVEL: </span>
<span id="level-count" class="text-yellow-300">01</span>
</div>
</div>
</div>
<!-- Password Display -->
<div class="bg-black p-4 rounded-lg border-2 border-green-500 mb-6 relative">
<div class="flex justify-between items-center">
<span class="text-green-400">PASSWORD:</span>
<div class="flex gap-2">
<button id="copy-btn" class="arcade-btn bg-blue-600 hover:bg-blue-500 text-white px-3 py-1 rounded bounce">
COPY
</button>
<button id="save-btn" class="arcade-btn bg-pink-600 hover:bg-pink-500 text-white px-3 py-1 rounded bounce">
SAVE
</button>
</div>
</div>
<div id="password-display" class="text-2xl md:text-3xl text-center py-4 my-2 bg-gray-800 rounded border border-gray-700 relative">
<span id="password-text" class="text-yellow-300">PRESS GENERATE</span>
<span id="cursor" class="blink text-green-400">|</span>
</div>
</div>
<!-- Generator Controls -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
<div class="bg-gray-800 p-4 rounded-lg border-2 border-blue-400">
<h3 class="text-blue-400 mb-2 text-center">MODE</h3>
<div class="flex flex-col gap-2">
<button id="friendly-btn" class="arcade-btn bg-green-700 hover:bg-green-600 text-white py-2 rounded bounce">
FRIENDLY
</button>
<button id="strong-btn" class="arcade-btn bg-yellow-600 hover:bg-yellow-500 text-white py-2 rounded bounce">
STRONG
</button>
<button id="custom-btn" class="arcade-btn bg-purple-700 hover:bg-purple-600 text-white py-2 rounded bounce">
CUSTOM
</button>
</div>
</div>
<div class="bg-gray-800 p-4 rounded-lg border-2 border-pink-400">
<h3 class="text-pink-400 mb-2 text-center">LENGTH</h3>
<div class="flex flex-col items-center">
<input id="length-slider" type="range" min="4" max="32" value="12" class="w-full mb-2">
<span id="length-value" class="text-yellow-300">12</span>
</div>
</div>
<div id="custom-options" class="bg-gray-800 p-4 rounded-lg border-2 border-green-400 hidden">
<h3 class="text-green-400 mb-2 text-center">CUSTOM OPTIONS</h3>
<div class="flex flex-col gap-2">
<label class="flex items-center">
<input type="checkbox" id="uppercase" checked class="mr-2">
<span>Uppercase (A-Z)</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="lowercase" checked class="mr-2">
<span>Lowercase (a-z)</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="numbers" checked class="mr-2">
<span>Numbers (0-9)</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="symbols" checked class="mr-2">
<span>Symbols (!@#$)</span>
</label>
</div>
</div>
</div>
<!-- Seed Input -->
<div class="bg-gray-800 p-4 rounded-lg border-2 border-yellow-400 mb-6">
<h3 class="text-yellow-400 mb-2">SEED (OPTIONAL)</h3>
<div class="flex gap-2">
<input id="seed-input" type="text" placeholder="Enter seed for reproducibility" class="flex-1 bg-black text-white p-2 rounded border border-gray-700">
<button id="generate-btn" class="arcade-btn bg-red-600 hover:bg-red-500 text-white px-4 py-2 rounded-lg bounce flash">
GENERATE
</button>
</div>
</div>
<!-- Saved Passwords -->
<div class="bg-gray-800 p-4 rounded-lg border-2 border-purple-400">
<div class="flex justify-between items-center mb-4">
<h3 class="text-purple-400">SAVED PASSWORDS</h3>
<div class="flex gap-2">
<button id="download-btn" class="arcade-btn bg-blue-600 hover:bg-blue-500 text-white px-3 py-1 rounded bounce">
DOWNLOAD .TXT
</button>
<button id="clear-all-btn" class="arcade-btn bg-red-600 hover:bg-red-500 text-white px-3 py-1 rounded bounce">
CLEAR ALL
</button>
</div>
</div>
<div id="saved-passwords" class="space-y-2 max-h-64 overflow-y-auto">
<!-- Passwords will be added here -->
<div class="text-center text-gray-500 py-4">No passwords saved yet</div>
</div>
</div>
</div>
<!-- Sound toggle -->
<div class="fixed bottom-4 right-4">
<button id="sound-toggle" class="arcade-btn bg-gray-800 hover:bg-gray-700 text-white p-3 rounded-full bounce">
<i class="fas fa-volume-up"></i>
</button>
</div>
<script>
// DOM Elements
const passwordDisplay = document.getElementById('password-text');
const cursor = document.getElementById('cursor');
const lengthSlider = document.getElementById('length-slider');
const lengthValue = document.getElementById('length-value');
const generateBtn = document.getElementById('generate-btn');
const copyBtn = document.getElementById('copy-btn');
const saveBtn = document.getElementById('save-btn');
const friendlyBtn = document.getElementById('friendly-btn');
const strongBtn = document.getElementById('strong-btn');
const customBtn = document.getElementById('custom-btn');
const customOptions = document.getElementById('custom-options');
const uppercaseCheck = document.getElementById('uppercase');
const lowercaseCheck = document.getElementById('lowercase');
const numbersCheck = document.getElementById('numbers');
const symbolsCheck = document.getElementById('symbols');
const seedInput = document.getElementById('seed-input');
const savedPasswords = document.getElementById('saved-passwords');
const savedCount = document.getElementById('saved-count');
const levelCount = document.getElementById('level-count');
const downloadBtn = document.getElementById('download-btn');
const clearAllBtn = document.getElementById('clear-all-btn');
const soundToggle = document.getElementById('sound-toggle');
const notification = document.getElementById('notification');
const notificationText = document.getElementById('notification-text');
// State
let currentPassword = '';
let savedPasswordsList = JSON.parse(localStorage.getItem('savedPasswords')) || [];
let soundEnabled = true;
let level = 1;
// Initialize
updateSavedPasswordsDisplay();
updateLevel();
// Event Listeners
lengthSlider.addEventListener('input', () => {
lengthValue.textContent = lengthSlider.value;
});
generateBtn.addEventListener('click', generatePassword);
copyBtn.addEventListener('click', copyPassword);
saveBtn.addEventListener('click', savePassword);
friendlyBtn.addEventListener('click', () => setMode('friendly'));
strongBtn.addEventListener('click', () => setMode('strong'));
customBtn.addEventListener('click', () => setMode('custom'));
downloadBtn.addEventListener('click', downloadPasswords);
clearAllBtn.addEventListener('click', clearAllPasswords);
soundToggle.addEventListener('click', toggleSound);
// Set initial mode
setMode('friendly');
// Functions
function setMode(mode) {
// Reset all buttons
friendlyBtn.classList.remove('glow');
strongBtn.classList.remove('glow');
customBtn.classList.remove('glow');
// Hide custom options by default
customOptions.classList.add('hidden');
// Set the selected mode
switch(mode) {
case 'friendly':
friendlyBtn.classList.add('glow');
lengthSlider.value = 8;
lengthValue.textContent = '8';
break;
case 'strong':
strongBtn.classList.add('glow');
lengthSlider.value = 16;
lengthValue.textContent = '16';
break;
case 'custom':
customBtn.classList.add('glow');
customOptions.classList.remove('hidden');
break;
}
// Play sound if enabled
if (soundEnabled) {
playSound('click');
}
}
function generatePassword() {
const length = parseInt(lengthSlider.value);
const seed = seedInput.value;
let charset = '';
let password = '';
// Determine character set based on mode
if (friendlyBtn.classList.contains('glow')) {
// Friendly mode - easy to remember words
const words = ['apple', 'banana', 'cherry', 'dragon', 'elephant', 'flamingo', 'giraffe', 'honey', 'iguana', 'jelly', 'koala', 'lemon', 'mango', 'ninja', 'orange', 'panda', 'quokka', 'rainbow', 'sunshine', 'tiger', 'unicorn', 'volcano', 'watermelon', 'xylophone', 'yellow', 'zebra'];
const separators = ['-', '_', '.', '!', '@', '#', '$', '%', '&', '*'];
// Generate a pattern like word-separator-word-number
const word1 = words[Math.floor(Math.random() * words.length)];
const word2 = words[Math.floor(Math.random() * words.length)];
const separator = separators[Math.floor(Math.random() * separators.length)];
const num = Math.floor(Math.random() * 90) + 10; // 10-99
password = `${word1}${separator}${word2}${num}`;
// If seed is provided, use it to generate predictable results
if (seed) {
const seedNum = hashSeed(seed);
const w1 = words[seedNum % words.length];
const w2 = words[(seedNum + 1) % words.length];
const sep = separators[(seedNum + 2) % separators.length];
const n = (seedNum % 90) + 10;
password = `${w1}${sep}${w2}${n}`;
}
// Ensure the password isn't too long
if (password.length > length) {
password = password.substring(0, length);
}
}
else if (strongBtn.classList.contains('glow')) {
// Strong mode - completely random characters
charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?';
if (seed) {
// Use seed for reproducibility
const seedNum = hashSeed(seed);
for (let i = 0; i < length; i++) {
const index = (seedNum + i) % charset.length;
password += charset.charAt(index);
}
} else {
// Completely random
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * charset.length);
password += charset.charAt(randomIndex);
}
}
}
else {
// Custom mode - use selected character sets
if (uppercaseCheck.checked) charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (lowercaseCheck.checked) charset += 'abcdefghijklmnopqrstuvwxyz';
if (numbersCheck.checked) charset += '0123456789';
if (symbolsCheck.checked) charset += '!@#$%^&*()_+-=[]{}|;:,.<>?';
if (charset.length === 0) {
showNotification('Please select at least one character set!', 'red');
return;
}
if (seed) {
// Use seed for reproducibility
const seedNum = hashSeed(seed);
for (let i = 0; i < length; i++) {
const index = (seedNum + i) % charset.length;
password += charset.charAt(index);
}
} else {
// Completely random
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * charset.length);
password += charset.charAt(randomIndex);
}
}
}
currentPassword = password;
// Animate the password display
passwordDisplay.textContent = '';
let i = 0;
const typingEffect = setInterval(() => {
if (i < password.length) {
passwordDisplay.textContent += password.charAt(i);
i++;
// Play typing sound if enabled
if (soundEnabled && i % 2 === 0) {
playSound('type');
}
} else {
clearInterval(typingEffect);
// Show success notification
showNotification('PASSWORD GENERATED!', 'green');
// Play success sound if enabled
if (soundEnabled) {
playSound('success');
}
}
}, 50);
// Animate the generate button
generateBtn.classList.add('flash');
setTimeout(() => {
generateBtn.classList.remove('flash');
}, 300);
}
function copyPassword() {
if (!currentPassword) {
showNotification('No password to copy!', 'red');
return;
}
navigator.clipboard.writeText(currentPassword)
.then(() => {
showNotification('COPIED TO CLIPBOARD!', 'blue');
// Animate the copy button
copyBtn.classList.add('flash');
setTimeout(() => {
copyBtn.classList.remove('flash');
}, 300);
// Play sound if enabled
if (soundEnabled) {
playSound('click');
}
})
.catch(err => {
console.error('Failed to copy: ', err);
showNotification('Failed to copy!', 'red');
});
}
function savePassword() {
if (!currentPassword) {
showNotification('No password to save!', 'red');
return;
}
// Check if password already exists
if (savedPasswordsList.includes(currentPassword)) {
showNotification('Password already saved!', 'yellow');
return;
}
// Add to saved passwords
savedPasswordsList.push(currentPassword);
localStorage.setItem('savedPasswords', JSON.stringify(savedPasswordsList));
// Update display
updateSavedPasswordsDisplay();
// Show success notification
showNotification('PASSWORD SAVED!', 'green');
// Animate the save button
saveBtn.classList.add('flash');
setTimeout(() => {
saveBtn.classList.remove('flash');
}, 300);
// Play sound if enabled
if (soundEnabled) {
playSound('coin');
}
// Check for level up
checkLevelUp();
}
function updateSavedPasswordsDisplay() {
savedPasswords.innerHTML = '';
if (savedPasswordsList.length === 0) {
savedPasswords.innerHTML = '<div class="text-center text-gray-500 py-4">No passwords saved yet</div>';
savedCount.textContent = '00';
return;
}
savedCount.textContent = savedPasswordsList.length.toString().padStart(2, '0');
savedPasswordsList.forEach((password, index) => {
const passwordItem = document.createElement('div');
passwordItem.className = 'password-item bg-gray-700 p-3 rounded-lg border border-gray-600 flex justify-between items-center';
passwordItem.innerHTML = `
<div class="flex items-center">
<span class="text-yellow-400 mr-2">${(index + 1).toString().padStart(2, '0')}</span>
<span class="text-green-300 font-mono">${password}</span>
</div>
<button class="delete-btn arcade-btn bg-red-600 hover:bg-red-500 text-white px-2 py-1 rounded bounce" data-index="${index}">
<i class="fas fa-trash"></i>
</button>
`;
savedPasswords.appendChild(passwordItem);
});
// Add event listeners to delete buttons
document.querySelectorAll('.delete-btn').forEach(btn => {
btn.addEventListener('click', function() {
const index = parseInt(this.getAttribute('data-index'));
deletePassword(index);
});
});
}
function deletePassword(index) {
savedPasswordsList.splice(index, 1);
localStorage.setItem('savedPasswords', JSON.stringify(savedPasswordsList));
updateSavedPasswordsDisplay();
// Show notification
showNotification('PASSWORD DELETED!', 'red');
// Play sound if enabled
if (soundEnabled) {
playSound('delete');
}
}
function clearAllPasswords() {
if (savedPasswordsList.length === 0) {
showNotification('No passwords to clear!', 'red');
return;
}
savedPasswordsList = [];
localStorage.setItem('savedPasswords', JSON.stringify(savedPasswordsList));
updateSavedPasswordsDisplay();
// Show notification
showNotification('ALL PASSWORDS CLEARED!', 'red');
// Animate the clear button
clearAllBtn.classList.add('flash');
setTimeout(() => {
clearAllBtn.classList.remove('flash');
}, 300);
// Play sound if enabled
if (soundEnabled) {
playSound('delete');
}
// Reset level
level = 1;
updateLevel();
}
function downloadPasswords() {
if (savedPasswordsList.length === 0) {
showNotification('No passwords to download!', 'red');
return;
}
const content = savedPasswordsList.join('\n\n');
const blob = new Blob([content], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'arcade-passwords.txt';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
// Show notification
showNotification('DOWNLOAD STARTED!', 'blue');
// Animate the download button
downloadBtn.classList.add('flash');
setTimeout(() => {
downloadBtn.classList.remove('flash');
}, 300);
// Play sound if enabled
if (soundEnabled) {
playSound('click');
}
}
function toggleSound() {
soundEnabled = !soundEnabled;
soundToggle.innerHTML = soundEnabled ? '<i class="fas fa-volume-up"></i>' : '<i class="fas fa-volume-mute"></i>';
// Show notification
showNotification(soundEnabled ? 'SOUND ON!' : 'SOUND OFF!', soundEnabled ? 'green' : 'red');
// Play sound if enabling
if (soundEnabled) {
playSound('click');
}
}
function showNotification(message, color) {
notificationText.textContent = message;
notification.className = `notification bg-${color}-600 p-4 rounded-lg shadow-lg border-2 border-${color === 'yellow' ? 'yellow-400' : color === 'red' ? 'red-400' : color === 'blue' ? 'blue-400' : 'green-400'} show`;
setTimeout(() => {
notification.classList.remove('show');
}, 3000);
}
function playSound(type) {
if (!soundEnabled) return;
// In a real app, you would play actual sound files here
// For this demo, we'll just log the sound type
console.log(`Playing ${type} sound`);
}
function hashSeed(seed) {
// Simple hash function for seed reproducibility
let hash = 0;
for (let i = 0; i < seed.length; i++) {
const char = seed.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return Math.abs(hash);
}
function checkLevelUp() {
const passwordsCount = savedPasswordsList.length;
const newLevel = Math.floor(passwordsCount / 5) + 1;
if (newLevel > level) {
level = newLevel;
updateLevel();
showNotification('LEVEL UP!', 'pink');
// Play level up sound if enabled
if (soundEnabled) {
playSound('levelup');
}
}
}
function updateLevel() {
levelCount.textContent = level.toString().padStart(2, '0');
}
</script>
<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=intipires/pwd-gen" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p><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=NzService/password-generator" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>