概述
密碼產生器是一個專業的安全工具,專為創建高強度密碼而設計。支援自定義字符集、批次生成、即時強度評估和多格式導出。 採用 Web Crypto API 的加密級隨機數生成,確保密碼的安全性和不可預測性。 提供單一模式和批次模式兩種操作方式,滿足個人和企業級需求。
🔒 加密級安全保證
🔒 Cryptographic Security Guarantee
使用 Web Crypto API 的 crypto.getRandomValues() 生成加密級隨機數,確保密碼具有最高級別的安全性和隨機性。
技術架構與核心設計
整體架構設計
Overall Architecture Design
技術項目 | 實作方式 | 設計考量 |
---|---|---|
隨機數生成 | Web Crypto API (crypto.getRandomValues) | 加密級安全性,符合國際標準 |
密碼評估 | 多因子評分系統 | 長度、字符多樣性、模式檢查 |
字符集管理 | 可配置字符集組合 | 靈活性與安全性平衡 |
批次處理 | 高效能迴圈生成 | 支援最多1000筆密碼 |
導出功能 | TXT/CSV 多格式下載 | 企業級資料管理需求 |
核心類別架構
Core Class Architecture
class PasswordGenerator {
constructor() {
this.mode = 'single'; // 'single' 或 'batch'
this.passwords = []; // 批次密碼儲存
this.currentLanguage = 'zh'; // 當前語言
this.maxFiles = 1000; // 最大批次數量
this.supportedCharsets = {
uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
lowercase: 'abcdefghijklmnopqrstuvwxyz',
numbers: '0123456789',
symbols: '!@#$%^&*()_+-=[]{}|;:,.<>?'
};
this.init();
}
init() {
this.setupGlobalLanguageListener(); // 必須最先執行
this.bindEvents();
this.updateLanguage();
this.updateStrengthMeter();
}
}
關鍵功能實現
- 🔐 加密級隨機生成:使用 Web Crypto API 確保密碼的不可預測性
- ⚙️ 自定義字符集:支援大寫、小寫、數字、特殊符號的靈活組合
- 📊 即時強度評估:多因子評分系統提供即時密碼強度分析
- 🔄 雙操作模式:單一密碼生成和批次密碼生成
- 📈 視覺化強度指示:彩色進度條和詳細評分顯示
- 📋 一鍵複製:支援單一密碼和批次密碼的快速複製
- 💾 多格式導出:TXT 和 CSV 格式下載,適合不同用途
- 🌐 完整雙語支援:中英文介面無縫切換
⚠️ 安全建議
⚠️ Security Recommendations
建議使用至少12字符長度,並包含多種字符類型。定期更換重要帳戶密碼,避免在多個網站使用相同密碼。
完整程式碼實作
以下是密碼產生器的完整程式碼實作,按功能模組分類展示。點擊卡片標題可展開查看詳細程式碼:
📦 核心密碼產生器類別
密碼產生器的核心類別實作,包含完整的建構函數、屬性定義、雙語翻譯系統和基本初始化流程。 這個類別是整個密碼產生系統的基礎,負責管理所有狀態和配置。
class PasswordGenerator {
constructor() {
// 基本狀態管理 / Basic state management
this.mode = 'single'; // 操作模式:'single' 或 'batch'
this.passwords = []; // 批次密碼儲存陣列
this.currentLanguage = 'zh'; // 當前語言設定
this.maxFiles = 1000; // 最大批次生成數量限制
// 完整的雙語翻譯字典 / Complete bilingual translation dictionary
this.translations = {
zh: {
title: '🔒 密碼產生器',
modeToggleBatch: '切換至批次模式',
modeToggleSingle: '切換至單一模式',
passwordSettings: '🔧 密碼設定',
passwordLength: '密碼長度',
passwordElements: '密碼組成元素',
uppercase: '大寫字母 (A-Z)',
lowercase: '小寫字母 (a-z)',
numbers: '數字 (0-9)',
symbols: '特殊符號 (!@#$%^&*)',
generatePassword: '🎲 產生密碼',
generatedPassword: '產生的密碼',
copyBtn: '複製',
copiedBtn: '已複製!',
passwordPlaceholder: '點擊「產生密碼」來生成您的安全密碼',
batchTitle: '📋 批次密碼產生',
batchCount: '產生數量',
batchUnit: '筆密碼',
batchGenerate: '🎲 批次產生',
copyAll: '📋 複製全部',
downloadTxt: '📄 下載 TXT',
downloadCsv: '📊 下載 CSV',
batchList: '批次密碼列表',
noPasswordsGenerated: '尚未產生任何密碼',
passwordStrength: '密碼強度',
weak: '弱',
medium: '中等',
strong: '強',
alertCharType: '請至少選擇一種字符類型!',
alertBatchRange: '產生數量必須介於 1 到 1000 之間!',
csvHeader: '編號,密碼'
},
en: {
title: '🔒 Password Generator',
modeToggleBatch: 'Switch to Batch Mode',
modeToggleSingle: 'Switch to Single Mode',
passwordSettings: '🔧 Password Settings',
passwordLength: 'Password Length',
passwordElements: 'Password Components',
uppercase: 'Uppercase Letters (A-Z)',
lowercase: 'Lowercase Letters (a-z)',
numbers: 'Numbers (0-9)',
symbols: 'Special Symbols (!@#$%^&*)',
generatePassword: '🎲 Generate Password',
generatedPassword: 'Generated Password',
copyBtn: 'Copy',
copiedBtn: 'Copied!',
passwordPlaceholder: 'Click "Generate Password" to create your secure password',
batchTitle: '📋 Batch Password Generation',
batchCount: 'Generate Quantity',
batchUnit: 'passwords',
batchGenerate: '🎲 Batch Generate',
copyAll: '📋 Copy All',
downloadTxt: '📄 Download TXT',
downloadCsv: '📊 Download CSV',
batchList: 'Batch Password List',
noPasswordsGenerated: 'No passwords generated yet',
passwordStrength: 'Password Strength',
weak: 'Weak',
medium: 'Medium',
strong: 'Strong',
alertCharType: 'Please select at least one character type!',
alertBatchRange: 'Generation quantity must be between 1 and 1000!',
csvHeader: 'No.,Password'
}
};
// 初始化工具 / Initialize tool
this.init();
}
/**
* 工具初始化流程 / Tool initialization process
* 按順序執行:語言監聽器 → 事件綁定 → 語言更新 → 強度計量器
*/
init() {
this.setupGlobalLanguageListener(); // 必須最先執行
this.bindEvents(); // 綁定所有事件監聽器
this.updateLanguage(); // 更新介面語言
this.updateStrengthMeter(); // 初始化密碼強度顯示
}
}
🌐 全域語言系統整合
實現與 Tool Master 全域語言系統的完美整合,包含語言切換監聽器、時序處理和語言同步機制。 確保工具能夠響應全站的語言切換事件,並正確處理初始化時序問題。
/**
* 全域語言系統整合 / Global Language System Integration
* 處理與 Tool Master 主站語言系統的雙向通信
*/
setupGlobalLanguageListener() {
// 監聽全域語言切換事件 / Listen for global language change events
window.addEventListener('languageChanged', (event) => {
this.currentLanguage = event.detail.language;
this.updateLanguage();
console.log(`密碼產生器語言已切換至: ${this.currentLanguage}`);
});
// 處理全域語言系統加載時序問題 / Handle global language system loading timing
const checkGlobalLanguage = () => {
if (window.globalI18n) {
// 同步當前語言設定 / Sync current language setting
this.currentLanguage = window.globalI18n.currentLanguage;
this.updateLanguage();
console.log(`同步全域語言設定: ${this.currentLanguage}`);
return true;
}
return false;
};
// 立即檢查,如果沒有就延遲重試 / Immediate check, retry if not available
if (!checkGlobalLanguage()) {
setTimeout(() => {
checkGlobalLanguage();
}, 100);
}
}
/**
* 完整的語言更新方法 / Complete language update method
* 更新所有介面元素的文字內容,確保無遺漏
*/
updateLanguage() {
const t = this.translations[this.currentLanguage];
// 更新主要標題 / Update main title
const title = document.querySelector('.password-generator-standalone h1');
if (title) title.textContent = t.title;
// 更新模式切換按鈕 / Update mode toggle button
const modeToggle = document.getElementById('modeToggle');
if (modeToggle) {
modeToggle.textContent = this.mode === 'single' ? t.modeToggleBatch : t.modeToggleSingle;
}
// 更新密碼設定區塊標題 / Update password settings section title
const singleTitle = document.querySelector('#singleMode h2');
if (singleTitle) singleTitle.textContent = t.passwordSettings;
// 更新密碼長度標籤 / Update password length label
const lengthLabel = document.querySelector('label[for="passwordLength"]');
if (lengthLabel) lengthLabel.textContent = t.passwordLength;
// 更新密碼組成元素標籤 / Update password components label
const controlGroups = document.querySelectorAll('.control-group');
controlGroups.forEach(group => {
const label = group.querySelector('label');
if (label && !label.getAttribute('for') &&
(label.textContent === '密碼組成元素' || label.textContent === 'Password Components')) {
label.textContent = t.passwordElements;
}
});
// 更新字符類型選項標籤 / Update character type option labels
const uppercaseLabel = document.querySelector('label[for="includeUppercase"]');
if (uppercaseLabel) uppercaseLabel.textContent = t.uppercase;
const lowercaseLabel = document.querySelector('label[for="includeLowercase"]');
if (lowercaseLabel) lowercaseLabel.textContent = t.lowercase;
const numbersLabel = document.querySelector('label[for="includeNumbers"]');
if (numbersLabel) numbersLabel.textContent = t.numbers;
const symbolsLabel = document.querySelector('label[for="includeSymbols"]');
if (symbolsLabel) symbolsLabel.textContent = t.symbols;
// 更新所有按鈕文字 / Update all button texts
this.updateButtons(t);
// 更新批次模式介面 / Update batch mode interface
this.updateBatchModeLanguage(t);
// 更新密碼強度顯示 / Update password strength display
this.updatePasswordStrengthLanguage(t);
}
/**
* 更新按鈕文字的輔助方法 / Helper method to update button texts
*/
updateButtons(t) {
const generateBtn = document.getElementById('generateBtn');
if (generateBtn) generateBtn.textContent = t.generatePassword;
const copyBtn = document.getElementById('copyBtn');
if (copyBtn && !copyBtn.textContent.includes('已複製') && !copyBtn.textContent.includes('Copied')) {
copyBtn.textContent = t.copyBtn;
}
const batchGenerateBtn = document.getElementById('batchGenerateBtn');
if (batchGenerateBtn) batchGenerateBtn.textContent = t.batchGenerate;
const copyAllBtn = document.getElementById('copyAllBtn');
if (copyAllBtn) copyAllBtn.textContent = t.copyAll;
const downloadTxtBtn = document.getElementById('downloadTxtBtn');
if (downloadTxtBtn) downloadTxtBtn.textContent = t.downloadTxt;
const downloadCsvBtn = document.getElementById('downloadCsvBtn');
if (downloadCsvBtn) downloadCsvBtn.textContent = t.downloadCsv;
}
🎯 事件綁定與DOM初始化
完整的事件監聽器設定,包含模式切換、密碼生成、複製功能、批次操作和下載功能。 實現雙向數據綁定,確保 UI 和數據狀態的完美同步。
/**
* 事件綁定與DOM初始化 / Event Binding & DOM Initialization
* 設置所有必要的事件監聽器,實現完整的用戶互動功能
*/
bindEvents() {
// 模式切換事件 / Mode switching event
const modeToggleBtn = document.getElementById('modeToggle');
if (modeToggleBtn) {
modeToggleBtn.addEventListener('click', () => {
this.toggleMode();
});
}
// 密碼長度雙向同步 / Password length two-way sync
const passwordLengthSlider = document.getElementById('passwordLength');
const passwordLengthNumber = document.getElementById('passwordLengthNum');
if (passwordLengthSlider) {
passwordLengthSlider.addEventListener('input', (e) => {
if (passwordLengthNumber) {
passwordLengthNumber.value = e.target.value;
}
this.updateStrengthMeter(); // 即時更新強度指示器
});
}
if (passwordLengthNumber) {
passwordLengthNumber.addEventListener('input', (e) => {
if (passwordLengthSlider) {
passwordLengthSlider.value = e.target.value;
}
this.updateStrengthMeter(); // 即時更新強度指示器
});
}
// 字符選項變化監聽 / Character option change listeners
const characterOptions = ['includeUppercase', 'includeLowercase', 'includeNumbers', 'includeSymbols'];
characterOptions.forEach(optionId => {
const checkbox = document.getElementById(optionId);
if (checkbox) {
checkbox.addEventListener('change', () => {
this.updateStrengthMeter(); // 字符選項變化時更新強度評估
});
}
});
// 單一密碼生成 / Single password generation
const generateBtn = document.getElementById('generateBtn');
if (generateBtn) {
generateBtn.addEventListener('click', () => {
this.generateSinglePassword();
});
}
// 單一密碼複製 / Single password copy
const copyBtn = document.getElementById('copyBtn');
if (copyBtn) {
copyBtn.addEventListener('click', () => {
this.copyPassword();
});
}
// 批次密碼生成 / Batch password generation
const batchGenerateBtn = document.getElementById('batchGenerateBtn');
if (batchGenerateBtn) {
batchGenerateBtn.addEventListener('click', () => {
this.generateBatchPasswords();
});
}
// 批次密碼複製全部 / Batch password copy all
const copyAllBtn = document.getElementById('copyAllBtn');
if (copyAllBtn) {
copyAllBtn.addEventListener('click', () => {
this.copyAllPasswords();
});
}
// 下載功能事件 / Download functionality events
this.bindDownloadEvents();
}
/**
* 下載功能事件綁定 / Download functionality event binding
* 處理 TXT 和 CSV 格式的批次密碼下載
*/
bindDownloadEvents() {
const downloadTxtBtn = document.getElementById('downloadTxtBtn');
if (downloadTxtBtn) {
downloadTxtBtn.addEventListener('click', () => {
this.downloadPasswords('txt');
});
}
const downloadCsvBtn = document.getElementById('downloadCsvBtn');
if (downloadCsvBtn) {
downloadCsvBtn.addEventListener('click', () => {
this.downloadPasswords('csv');
});
}
}
/**
* 模式切換功能 / Mode switching functionality
* 在單一模式和批次模式之間切換,包含 UI 更新
*/
toggleMode() {
const modeToggle = document.getElementById('modeToggle');
const singleMode = document.getElementById('singleMode');
const batchMode = document.getElementById('batchMode');
const t = this.translations[this.currentLanguage];
if (!modeToggle || !singleMode || !batchMode) {
console.error('模式切換: 找不到必要的 DOM 元素');
return;
}
if (this.mode === 'single') {
// 切換到批次模式 / Switch to batch mode
this.mode = 'batch';
modeToggle.textContent = t.modeToggleSingle;
singleMode.style.display = 'none';
batchMode.classList.add('active');
console.log('已切換到批次模式');
} else {
// 切換到單一模式 / Switch to single mode
this.mode = 'single';
modeToggle.textContent = t.modeToggleBatch;
singleMode.style.display = 'block';
batchMode.classList.remove('active');
console.log('已切換到單一模式');
}
}
⚙️ 密碼生成核心引擎
密碼生成的核心算法實作,使用 Web Crypto API 的加密級隨機數生成。 包含字符集組合、安全隨機生成、單一和批次模式的完整實現。
/**
* 字符集獲取與組合 / Character set retrieval and combination
* 根據用戶選擇動態組合可用字符集
*/
getCharacterSet() {
let charset = '';
// 檢查大寫字母選項 / Check uppercase letters option
if (document.getElementById('includeUppercase')?.checked) {
charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
}
// 檢查小寫字母選項 / Check lowercase letters option
if (document.getElementById('includeLowercase')?.checked) {
charset += 'abcdefghijklmnopqrstuvwxyz';
}
// 檢查數字選項 / Check numbers option
if (document.getElementById('includeNumbers')?.checked) {
charset += '0123456789';
}
// 檢查特殊符號選項 / Check special symbols option
if (document.getElementById('includeSymbols')?.checked) {
charset += '!@#$%^&*()_+-=[]{}|;:,.<>?';
}
return charset;
}
/**
* 加密級安全密碼生成 / Cryptographic-grade secure password generation
* 使用 Web Crypto API 確保真正的隨機性和安全性
*/
generatePassword(length, charset) {
// 驗證參數有效性 / Validate parameter validity
if (!charset || charset.length === 0) {
console.error('字符集為空,無法生成密碼');
return '';
}
if (length < 1 || length > 128) {
console.error('密碼長度必須在 1-128 之間');
return '';
}
let password = '';
try {
// 使用 Web Crypto API 生成加密級隨機數 / Use Web Crypto API for cryptographic random numbers
const array = new Uint32Array(length);
crypto.getRandomValues(array);
// 將隨機數映射到字符集 / Map random numbers to character set
for (let i = 0; i < length; i++) {
const randomIndex = array[i] % charset.length;
password += charset[randomIndex];
}
console.log(`成功生成 ${length} 字符密碼,使用字符集長度: ${charset.length}`);
} catch (error) {
console.error('密碼生成失敗:', error);
// 備用方案:使用 Math.random() (較不安全)
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * charset.length);
password += charset[randomIndex];
}
console.warn('已降級使用 Math.random() 生成密碼');
}
return password;
}
/**
* 單一密碼生成功能 / Single password generation functionality
* 處理單一模式下的密碼生成和顯示
*/
generateSinglePassword() {
const lengthInput = document.getElementById('passwordLength');
const length = lengthInput ? parseInt(lengthInput.value) : 12;
const charset = this.getCharacterSet();
const t = this.translations[this.currentLanguage];
// 驗證字符集選擇 / Validate character set selection
if (!charset) {
alert(t.alertCharType);
return;
}
// 生成密碼 / Generate password
const password = this.generatePassword(length, charset);
if (!password) {
console.error('密碼生成失敗');
return;
}
// 更新顯示介面 / Update display interface
const display = document.getElementById('passwordDisplay');
const copyBtn = document.getElementById('copyBtn');
if (display) {
display.textContent = password;
display.classList.remove('empty');
}
if (copyBtn) {
copyBtn.style.display = 'block';
}
// 更新密碼強度指示器 / Update password strength indicator
this.updateStrengthMeter(password);
console.log(`單一密碼生成完成: 長度 ${length}, 強度評估已更新`);
}
/**
* 批次密碼生成功能 / Batch password generation functionality
* 處理批次模式下的大量密碼生成
*/
generateBatchPasswords() {
const countInput = document.getElementById('batchCount');
const lengthInput = document.getElementById('passwordLength');
const count = countInput ? parseInt(countInput.value) : 10;
const length = lengthInput ? parseInt(lengthInput.value) : 12;
const charset = this.getCharacterSet();
const t = this.translations[this.currentLanguage];
// 驗證輸入參數 / Validate input parameters
if (!charset) {
alert(t.alertCharType);
return;
}
if (count < 1 || count > 1000) {
alert(t.alertBatchRange);
return;
}
// 清空之前的密碼列表 / Clear previous password list
this.passwords = [];
// 批次生成密碼 / Batch generate passwords
console.log(`開始批次生成 ${count} 個密碼,每個長度 ${length}`);
const startTime = performance.now();
for (let i = 0; i < count; i++) {
const password = this.generatePassword(length, charset);
if (password) {
this.passwords.push(password);
}
}
const endTime = performance.now();
console.log(`批次生成完成,耗時 ${(endTime - startTime).toFixed(2)}ms`);
// 更新顯示和啟用功能按鈕 / Update display and enable function buttons
this.displayBatchPasswords();
this.showBatchButtons();
}
🎨 密碼強度評估系統
多因子密碼強度評估算法,包含長度評分、字符多樣性分析、視覺化強度指示器和即時反饋系統。 提供弱、中等、強三級評估,幫助用戶創建更安全的密碼。
/**
* 密碼強度計算引擎 / Password strength calculation engine
* 基於多個因素的綜合評分算法
*/
calculateStrength(password) {
if (!password || password.length === 0) {
return { score: 0, text: '', class: 'weak' };
}
let score = 0;
const feedback = [];
// 長度評分 (最多 75 分) / Length scoring (max 75 points)
if (password.length >= 8) {
score += 25;
feedback.push('長度達到基本要求');
}
if (password.length >= 12) {
score += 25;
feedback.push('長度達到推薦標準');
}
if (password.length >= 16) {
score += 25;
feedback.push('長度達到高安全標準');
}
// 字符類型多樣性評分 (最多 25 分) / Character type diversity scoring (max 25 points)
let typeCount = 0;
if (/[a-z]/.test(password)) {
score += 6;
typeCount++;
feedback.push('包含小寫字母');
}
if (/[A-Z]/.test(password)) {
score += 6;
typeCount++;
feedback.push('包含大寫字母');
}
if (/[0-9]/.test(password)) {
score += 6;
typeCount++;
feedback.push('包含數字');
}
if (/[^A-Za-z0-9]/.test(password)) {
score += 7;
typeCount++;
feedback.push('包含特殊符號');
}
// 字符類型多樣性獎勵 / Character type diversity bonus
if (typeCount >= 3) {
score += 5;
feedback.push('字符類型豐富');
}
// 模式檢查 (扣分項目) / Pattern checking (penalty items)
if (/(.)\1{2,}/.test(password)) {
score -= 10;
feedback.push('包含重複字符(扣分)');
}
if (/123|abc|qwe/i.test(password)) {
score -= 15;
feedback.push('包含常見序列(扣分)');
}
// 確保分數在合理範圍內 / Ensure score is within reasonable range
score = Math.max(0, Math.min(100, score));
// 評級判斷 / Rating determination
const t = this.translations[this.currentLanguage];
let strengthClass, strengthText;
if (score < 30) {
strengthClass = 'weak';
strengthText = t.weak;
} else if (score < 60) {
strengthClass = 'medium';
strengthText = t.medium;
} else {
strengthClass = 'strong';
strengthText = t.strong;
}
console.log(`密碼強度評估: ${score}分 (${strengthText})`, feedback);
return {
score,
text: strengthText,
class: strengthClass,
feedback: feedback
};
}
/**
* 強度指示器更新 / Strength indicator update
* 更新視覺化的強度進度條和文字顯示
*/
updateStrengthMeter(password = null) {
const display = document.getElementById('passwordDisplay');
const strengthBar = document.getElementById('strengthBar');
const strengthText = document.getElementById('strengthText');
// 如果沒有指定密碼且顯示區域為空,則清空強度指示器
if (!password && display?.classList.contains('empty')) {
if (strengthBar) {
strengthBar.style.width = '0%';
strengthBar.className = 'strength-bar';
}
if (strengthText) {
strengthText.textContent = '';
strengthText.className = 'strength-text';
}
return;
}
// 如果沒有指定密碼,則生成測試密碼進行評估
const testPassword = password || this.generateTestPassword();
if (!testPassword) return;
// 計算強度 / Calculate strength
const strength = this.calculateStrength(testPassword);
const t = this.translations[this.currentLanguage];
// 更新進度條 / Update progress bar
if (strengthBar) {
strengthBar.style.width = strength.score + '%';
strengthBar.className = `strength-bar strength-${strength.class}`;
// 添加平滑過渡動畫 / Add smooth transition animation
strengthBar.style.transition = 'width 0.3s ease, background-color 0.3s ease';
}
// 更新文字顯示 / Update text display
if (strengthText) {
strengthText.textContent = `${t.passwordStrength}: ${strength.text} (${strength.score}%)`;
strengthText.className = `strength-text strength-${strength.class}`;
}
console.log(`強度指示器已更新: ${strength.score}% (${strength.class})`);
}
/**
* 生成測試密碼用於強度預覽 / Generate test password for strength preview
* 用於在用戶調整設定時提供即時的強度預覽
*/
generateTestPassword() {
const lengthInput = document.getElementById('passwordLength');
const length = lengthInput ? parseInt(lengthInput.value) : 12;
const charset = this.getCharacterSet();
if (!charset) {
return '';
}
// 生成簡化的測試密碼(不用於實際使用)
return this.generatePassword(Math.min(length, 16), charset);
}
🛠️ 複製與下載功能
完整的複製功能和多格式下載系統,包含單一密碼複製、批次密碼複製、TXT/CSV格式導出。 使用 Clipboard API 和 Blob 技術,提供現代化的文件處理體驗。
/**
* 單一密碼複製功能 / Single password copy functionality
* 使用現代 Clipboard API 進行安全的剪貼簿操作
*/
copyPassword() {
const passwordDisplay = document.getElementById('passwordDisplay');
if (!passwordDisplay) {
console.error('找不到密碼顯示元素');
return;
}
const password = passwordDisplay.textContent;
if (!password || passwordDisplay.classList.contains('empty')) {
console.warn('沒有可複製的密碼');
return;
}
const t = this.translations[this.currentLanguage];
const copyBtn = document.getElementById('copyBtn');
// 使用 Clipboard API 進行複製 / Use Clipboard API for copying
navigator.clipboard.writeText(password).then(() => {
console.log('密碼已複製到剪貼簿');
// 顯示複製成功反饋 / Show copy success feedback
if (copyBtn) {
const originalText = copyBtn.textContent;
copyBtn.textContent = t.copiedBtn;
copyBtn.style.background = '#27ae60';
// 1秒後恢復原狀 / Restore after 1 second
setTimeout(() => {
copyBtn.textContent = t.copyBtn;
copyBtn.style.background = '';
}, 1000);
}
}).catch(err => {
console.error('複製失敗:', err);
// 備用複製方案 / Fallback copy method
this.fallbackCopyToClipboard(password);
});
}
/**
* 批次密碼複製功能 / Batch password copy functionality
* 將所有生成的密碼複製為純文字格式
*/
copyAllPasswords() {
if (!this.passwords || this.passwords.length === 0) {
console.warn('沒有可複製的批次密碼');
return;
}
const allPasswords = this.passwords.join('\n');
const t = this.translations[this.currentLanguage];
const copyAllBtn = document.getElementById('copyAllBtn');
navigator.clipboard.writeText(allPasswords).then(() => {
console.log(`已複製 ${this.passwords.length} 個密碼到剪貼簿`);
// 顯示複製成功反饋 / Show copy success feedback
if (copyAllBtn) {
const originalText = copyAllBtn.textContent;
copyAllBtn.textContent = t.copiedBtn;
copyAllBtn.style.background = '#27ae60';
setTimeout(() => {
copyAllBtn.textContent = t.copyAll;
copyAllBtn.style.background = '';
}, 1000);
}
}).catch(err => {
console.error('批次複製失敗:', err);
this.fallbackCopyToClipboard(allPasswords);
});
}
/**
* 備用複製方案 / Fallback copy method
* 當 Clipboard API 不可用時的傳統複製方法
*/
fallbackCopyToClipboard(text) {
const textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.opacity = '0';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
const successful = document.execCommand('copy');
if (successful) {
console.log('備用複製方案成功');
} else {
console.error('備用複製方案也失敗了');
}
} catch (err) {
console.error('備用複製方案執行失敗:', err);
}
document.body.removeChild(textArea);
}
/**
* 多格式下載功能 / Multi-format download functionality
* 支援 TXT 和 CSV 格式的批次密碼下載
*/
downloadPasswords(format) {
if (!this.passwords || this.passwords.length === 0) {
console.warn('沒有可下載的密碼');
return;
}
let content = '';
let filename = '';
let mimeType = 'text/plain;charset=utf-8';
const t = this.translations[this.currentLanguage];
const timestamp = new Date().toISOString().slice(0, 10);
if (format === 'txt') {
// TXT 格式:純文字,每行一個密碼 / TXT format: plain text, one password per line
content = this.passwords.join('\n');
filename = `passwords_${timestamp}.txt`;
} else if (format === 'csv') {
// CSV 格式:結構化資料 / CSV format: structured data
const csvRows = this.passwords.map((pwd, index) => {
// 轉義密碼中的雙引號 / Escape double quotes in password
const escapedPassword = pwd.replace(/"/g, '""');
// 用雙引號包圍密碼以防止特殊字符問題 / Wrap password in quotes for special characters
return `${index + 1},"${escapedPassword}"`;
});
content = t.csvHeader + '\n' + csvRows.join('\n');
filename = `passwords_${timestamp}.csv`;
mimeType = 'text/csv;charset=utf-8';
} else {
console.error('不支援的下載格式:', format);
return;
}
// 使用 Blob API 創建檔案 / Use Blob API to create file
try {
const blob = new Blob([content], { type: mimeType });
const url = URL.createObjectURL(blob);
// 創建隱藏的下載連結 / Create hidden download link
const downloadLink = document.createElement('a');
downloadLink.href = url;
downloadLink.download = filename;
downloadLink.style.display = 'none';
// 觸發下載 / Trigger download
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
// 清理 URL 物件 / Clean up URL object
setTimeout(() => {
URL.revokeObjectURL(url);
}, 100);
console.log(`${format.toUpperCase()} 格式下載完成: ${filename} (${this.passwords.length} 個密碼)`);
} catch (error) {
console.error('下載失敗:', error);
alert(`下載失敗: ${error.message}`);
}
}
🚀 批次顯示與工具初始化
批次密碼的顯示管理和工具的完整初始化流程。包含密碼列表渲染、按鈕狀態管理、DOM就緒檢測和實例化。 確保工具在各種載入情況下都能正確初始化。
/**
* 批次密碼顯示管理 / Batch password display management
* 動態渲染批次生成的密碼列表
*/
displayBatchPasswords() {
const listElement = document.getElementById('batchPasswordList');
if (!listElement) {
console.error('找不到批次密碼列表元素');
return;
}
// 清空現有內容 / Clear existing content
listElement.innerHTML = '';
if (!this.passwords || this.passwords.length === 0) {
const t = this.translations[this.currentLanguage];
listElement.textContent = t.noPasswordsGenerated;
return;
}
// 渲染密碼列表 / Render password list
this.passwords.forEach((password, index) => {
const passwordItem = document.createElement('div');
passwordItem.className = 'password-item';
passwordItem.textContent = `${index + 1}. ${password}`;
// 添加點擊複製功能 / Add click-to-copy functionality
passwordItem.addEventListener('click', () => {
navigator.clipboard.writeText(password).then(() => {
console.log(`已複製密碼 #${index + 1}`);
// 短暫高亮效果 / Brief highlight effect
passwordItem.style.background = '#e8f5e8';
setTimeout(() => {
passwordItem.style.background = '';
}, 500);
}).catch(err => {
console.error('複製密碼失敗:', err);
});
});
// 添加 hover 提示 / Add hover tooltip
passwordItem.title = '點擊複製此密碼';
passwordItem.style.cursor = 'pointer';
listElement.appendChild(passwordItem);
});
console.log(`已顯示 ${this.passwords.length} 個批次密碼`);
}
/**
* 批次功能按鈕顯示管理 / Batch function button display management
* 控制批次模式下功能按鈕的顯示狀態
*/
showBatchButtons() {
const buttons = [
'copyAllBtn',
'downloadTxtBtn',
'downloadCsvBtn'
];
buttons.forEach(buttonId => {
const button = document.getElementById(buttonId);
if (button) {
button.style.display = 'inline-block';
// 添加淡入動畫效果 / Add fade-in animation effect
button.style.opacity = '0';
button.style.transition = 'opacity 0.3s ease';
requestAnimationFrame(() => {
button.style.opacity = '1';
});
}
});
console.log('批次功能按鈕已啟用');
}
/**
* 語言相關輔助更新方法 / Language-related helper update methods
* 更新批次模式和密碼強度的語言顯示
*/
updateBatchModeLanguage(t) {
// 更新批次模式標題 / Update batch mode title
const batchTitle = document.querySelector('#batchMode h2');
if (batchTitle) batchTitle.textContent = t.batchTitle;
// 更新批次數量標籤 / Update batch count label
const batchCountLabel = document.querySelector('label[for="batchCount"]');
if (batchCountLabel) batchCountLabel.textContent = t.batchCount;
// 更新單位文字 / Update unit text
const batchUnit = document.querySelector('.input-group span');
if (batchUnit && batchUnit.textContent.includes('筆密碼') || batchUnit.textContent.includes('passwords')) {
batchUnit.textContent = t.batchUnit;
}
// 更新批次列表標籤 / Update batch list label
const batchLabels = document.querySelectorAll('#batchMode .control-group label');
batchLabels.forEach(label => {
if (label.textContent === '批次密碼列表' || label.textContent === 'Batch Password List') {
label.textContent = t.batchList;
}
});
// 更新批次列表內容(如果為空) / Update batch list content (if empty)
const batchList = document.getElementById('batchPasswordList');
if (batchList && this.passwords.length === 0) {
batchList.textContent = t.noPasswordsGenerated;
}
}
updatePasswordStrengthLanguage(t) {
// 更新密碼強度文字 / Update password strength text
const strengthText = document.getElementById('strengthText');
if (strengthText && strengthText.textContent) {
const strengthClass = strengthText.className.split(' ').find(c => c.startsWith('strength-'));
if (strengthClass) {
const strength = strengthClass.replace('strength-', '');
const strengthMap = {
'weak': t.weak,
'medium': t.medium,
'strong': t.strong
};
const score = strengthText.textContent.match(/\d+/);
if (score && strengthMap[strength]) {
strengthText.textContent = `${t.passwordStrength}: ${strengthMap[strength]} (${score[0]}%)`;
}
}
}
}
/**
* 程式碼卡片切換功能 / Code card toggle functionality
* 為技術文檔頁面提供展開/收合功能
*/
function toggleCodeCard(header) {
const content = header.nextElementSibling;
const icon = header.querySelector('.toggle-icon');
if (content.style.display === 'none' || content.style.display === '') {
content.style.display = 'block';
header.classList.add('expanded');
icon.textContent = '▼';
} else {
content.style.display = 'none';
header.classList.remove('expanded');
icon.textContent = '▶';
}
}
}
// 工具初始化 / Tool initialization
// 確保 DOM 完全載入後再初始化密碼產生器
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM 已載入,開始初始化密碼產生器');
try {
// 檢查必要的 DOM 元素是否存在 / Check if necessary DOM elements exist
const requiredElements = [
'passwordLength',
'generateBtn',
'passwordDisplay'
];
const missingElements = requiredElements.filter(id => !document.getElementById(id));
if (missingElements.length > 0) {
console.warn('缺少必要元素:', missingElements);
// 延遲重試初始化 / Retry initialization with delay
setTimeout(() => {
new PasswordGenerator();
}, 500);
} else {
// 立即初始化 / Initialize immediately
window.passwordGenerator = new PasswordGenerator();
console.log('密碼產生器初始化完成');
}
} catch (error) {
console.error('密碼產生器初始化失敗:', error);
// 最後一次重試 / Final retry attempt
setTimeout(() => {
try {
window.passwordGenerator = new PasswordGenerator();
console.log('密碼產生器延遲初始化完成');
} catch (retryError) {
console.error('密碼產生器延遲初始化也失敗:', retryError);
}
}, 1000);
}
});
總結
密碼產生器展示了現代 Web 安全工具的最佳實踐,結合了加密級隨機數生成、多因子強度評估、雙語系統整合和企業級批次處理功能。 使用 Web Crypto API 確保了密碼的安全性,而完整的 UI/UX 設計則提供了優秀的用戶體驗。 這個實作可以作為其他安全工具開發的參考範例。