💡 設計亮點 / Key Features:
- 100% 本地運行 (100% Local Processing): 完全基於瀏覽器 JavaScript 的
crypto.getRandomValues() 加密安全隨機數,絕對不透過網路傳輸密碼,保障隱私。
- 雙語介面 (Bilingual Interface): 中英文完整對照,適合國際化或兩岸三地用戶。
- 無第三方依賴 (Zero Dependencies): 純原生 HTML/CSS/JS,加載速度微秒級,完美符合技術 SEO 需求。
原始碼使用說明 / How to Use
請將下方代碼複製並儲存為 index.html 檔案,直接上傳到您的伺服器、次網域(例如 password.mbsharesite.com)即可完美運作。無須任何後端資料庫。
Save the code below as index.html and host it anywhere. It runs fully client-side without any server-side database requirements.
完整原始碼 / Complete Source Code (index.html)
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Secure Password Generator | 安全密碼生成器</title>
<style>
:root {
--primary: #2563eb;
--primary-hover: #1d4ed8;
--bg: #f8fafc;
--card-bg: #ffffff;
--text: #0f172a;
--text-light: #64748b;
--border: #e2e8f0;
--success: #16a34a;
}
* { box-sizing: border-box; margin: 0; padding: 0; font-family: -apple-system, sans-serif; }
body { background-color: var(--bg); color: var(--text); padding: 20px; display: flex; justify-content: center; align-items: center; min-height: 100vh; }
.wrapper { width: 100%; max-width: 550px; background: var(--card-bg); padding: 30px; border-radius: 16px; box-shadow: 0 10px 25px -5px rgba(0,0,0,0.05); border: 1px solid var(--border); }
.lang-switch { display: flex; justify-content: flex-end; gap: 10px; margin-bottom: 20px; }
.lang-btn { background: none; border: none; color: var(--primary); cursor: pointer; font-size: 14px; font-weight: 600; }
.lang-btn:hover { text-decoration: underline; }
h1 { font-size: 24px; text-align: center; margin-bottom: 8px; color: var(--text); }
.subtitle { text-align: center; font-size: 14px; color: var(--text-light); margin-bottom: 25px; }
.result-container { position: relative; display: flex; background: var(--bg); border: 2px solid var(--border); border-radius: 12px; padding: 15px; margin-bottom: 25px; align-items: center; }
.result-input { width: 100%; background: transparent; border: none; outline: none; font-family: monospace; font-size: 18px; font-weight: 600; letter-spacing: 1px; color: var(--text); padding-right: 50px; }
.copy-btn { position: absolute; right: 10px; background: var(--primary); color: white; border: none; padding: 8px 14px; border-radius: 8px; cursor: pointer; font-size: 13px; font-weight: 500; transition: background 0.2s; }
.copy-btn:hover { background: var(--primary-hover); }
.setting-item { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; font-size: 15px; }
.slider-container { flex-direction: column; align-items: flex-start; gap: 8px; }
.slider-header { display: flex; width: 100%; justify-content: space-between; }
input[type="range"] { width: 100%; height: 6px; background: var(--border); border-radius: 5px; outline: none; -webkit-appearance: none; }
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; background: var(--primary); border-radius: 50%; cursor: pointer; }
input[type="checkbox"] { width: 18px; height: 18px; cursor: pointer; accent-color: var(--primary); }
.gen-btn { width: 100%; background: var(--primary); color: white; border: none; padding: 14px; border-radius: 12px; font-size: 16px; font-weight: 600; cursor: pointer; margin-top: 10px; transition: background 0.2s; }
.gen-btn:hover { background: var(--primary-hover); }
.security-badge { text-align: center; margin-top: 20px; font-size: 12px; color: var(--success); background: #f0fdf4; padding: 8px; border-radius: 8px; display: flex; align-items: center; justify-content: center; gap: 5px; }
</style>
</head>
<body>
<div class="wrapper">
<div class="lang-switch">
<button class="lang-btn" onclick="switchLang('en')">English</button>
<span style="color:var(--border)">|</span>
<button class="lang-btn" onclick="switchLang('zh')">繁體中文</button>
</div>
<h1 id="title">安全密碼生成器</h1>
<div class="subtitle" id="subtitle">100% 瀏覽器本地安全生成,隱私絕不上傳</div>
<div class="result-container">
<input type="text" id="password-display" class="result-input" readonly>
<button id="copy-btn" class="copy-btn" onclick="copyPassword()">複製 / Copy</button>
</div>
<div class="setting-item slider-container">
<div class="slider-header">
<span id="label-length">密碼長度</span>
<span id="length-val" style="font-weight:bold; color:var(--primary);">16</span>
</div>
<input type="range" id="length-slider" min="6" max="64" value="16" oninput="updateLengthLabel()">
</div>
<div class="setting-item">
<label for="include-uppercase" id="label-uppercase">包含大寫字母 (A-Z)</label>
<input type="checkbox" id="include-uppercase" checked>
</div>
<div class="setting-item">
<label for="include-lowercase" id="label-lowercase">包含小寫字母 (a-z)</label>
<input type="checkbox" id="include-lowercase" checked>
</div>
<div class="setting-item">
<label for="include-numbers" id="label-numbers">包含數字 (0-9)</label>
<input type="checkbox" id="include-numbers" checked>
</div>
<div class="setting-item">
<label for="include-symbols" id="label-symbols">包含特殊符號 (!@#$%^*)</label>
<input type="checkbox" id="include-symbols" checked>
</div>
<button id="gen-btn" class="gen-btn" onclick="generatePassword()">產生隨機密碼</button>
<div class="security-badge" id="security-badge">
🔒 密碼於本地瀏覽器生成,100% 保密
</div>
</div>
<script>
const langPack = {
zh: {
title: "安全密碼生成器",
subtitle: "100% 瀏覽器本地安全生成,隱私絕不上傳",
btnCopy: "複製",
btnCopied: "已複製!",
lblLength: "密碼長度",
lblUpper: "包含大寫字母 (A-Z)",
lblLower: "包含小寫字母 (a-z)",
lblNum: "包含數字 (0-9)",
lblSym: "包含特殊符號 (!@#$%^*)",
btnGen: "產生隨機密碼",
badge: "🔒 密碼於本地瀏覽器生成,100% 保密",
alertAlert: "請至少勾選一個字元編組!"
},
en: {
title: "Secure Password Generator",
subtitle: "100% client-side secure generation, privacy guaranteed",
btnCopy: "Copy",
btnCopied: "Copied!",
lblLength: "Password Length",
lblUpper: "Include Uppercase (A-Z)",
lblLower: "Include Lowercase (a-z)",
lblNum: "Include Numbers (0-9)",
lblSym: "Include Symbols (!@#$%^*)",
btnGen: "Generate Password",
badge: "🔒 Generated locally in-browser. Secure & private.",
alertAlert: "Please select at least one character set!"
}
};
let currentLang = 'zh';
function switchLang(lang) {
currentLang = lang;
const pack = langPack[lang];
document.getElementById('title').innerText = pack.title;
document.getElementById('subtitle').innerText = pack.subtitle;
document.getElementById('copy-btn').innerText = pack.btnCopy;
document.getElementById('label-length').innerText = pack.lblLength;
document.getElementById('label-uppercase').innerText = pack.lblUpper;
document.getElementById('label-lowercase').innerText = pack.lblLower;
document.getElementById('label-numbers').innerText = pack.lblNum;
document.getElementById('label-symbols').innerText = pack.lblSym;
document.getElementById('gen-btn').innerText = pack.btnGen;
document.getElementById('security-badge').innerText = pack.badge;
}
function updateLengthLabel() {
document.getElementById('length-val').innerText = document.getElementById('length-slider').value;
}
function generatePassword() {
const length = parseInt(document.getElementById('length-slider').value);
const hasUpper = document.getElementById('include-uppercase').checked;
const hasLower = document.getElementById('include-lowercase').checked;
const hasNum = document.getElementById('include-numbers').checked;
const hasSym = document.getElementById('include-symbols').checked;
const upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const lowerChars = "abcdefghijklmnopqrstuvwxyz";
const numChars = "0123456789";
const symChars = "!@#$%^&*()_+~`|}{[]:;?><,./-=";
let charPool = "";
if (hasUpper) charPool += upperChars;
if (hasLower) charPool += lowerChars;
if (hasNum) charPool += numChars;
if (hasSym) charPool += symChars;
if (charPool === "") {
alert(langPack[currentLang].alertAlert);
return;
}
let password = "";
// Use cryptographically secure pseudorandom number generator (CSPRNG)
const randomValues = new Uint32Array(length);
window.crypto.getRandomValues(randomValues);
for (let i = 0; i < length; i++) {
password += charPool.charAt(randomValues[i] % charPool.length);
}
document.getElementById('password-display').value = password;
document.getElementById('copy-btn').innerText = currentLang === 'zh' ? langPack.zh.btnCopy : langPack.en.btnCopy;
}
function copyPassword() {
const passInput = document.getElementById('password-display');
if (!passInput.value) return;
passInput.select();
passInput.setSelectionRange(0, 99999);
navigator.clipboard.writeText(passInput.value);
const copyBtn = document.getElementById('copy-btn');
copyBtn.innerText = langPack[currentLang].btnCopied;
setTimeout(() => {
copyBtn.innerText = currentLang === 'zh' ? langPack.zh.btnCopy : langPack.en.btnCopy;
}, 2000);
}
// Auto-generate on load
window.onload = function() {
generatePassword();
};
</script>
</body>
</html>