144 lines
5.3 KiB
PHP
144 lines
5.3 KiB
PHP
<?php
|
||
/**
|
||
* func/password.php —— 随机密码生成
|
||
* 字符集多选 + 自定义字符集 + 长度 + 一次生成多组 + 复制
|
||
*/
|
||
$P = '../';
|
||
require_once dirname(__DIR__) . '/includes/layout.php';
|
||
require_once __DIR__ . '/_bar.php';
|
||
|
||
layout_head('随机密码生成');
|
||
func_bar('随机密码生成');
|
||
?>
|
||
<main class="page-main">
|
||
<div class="wrap page-body">
|
||
<div class="panel-card">
|
||
<div class="field-row">
|
||
<label class="seg-check"><input type="checkbox" id="ckUpper" checked> 大写 A-Z</label>
|
||
<label class="seg-check"><input type="checkbox" id="ckLower" checked> 小写 a-z</label>
|
||
<label class="seg-check"><input type="checkbox" id="ckDigit" checked> 数字 0-9</label>
|
||
<label class="seg-check"><input type="checkbox" id="ckSym"> 特殊符号</label>
|
||
</div>
|
||
<div class="field-row" style="margin-top:6px">
|
||
<label class="seg-check"><input type="checkbox" id="ckCustom"> 使用自定义字符集</label>
|
||
<input type="text" id="inCustom" placeholder="自定义字符集(如:ABCabc!@#),勾选后启用" style="flex:1;min-width:260px">
|
||
</div>
|
||
<div class="field-row">
|
||
<label class="fl" style="margin:0">密码长度:<b id="lenVal">16</b></label>
|
||
<input type="range" id="lenRange" min="4" max="64" value="16" style="max-width:280px">
|
||
<label class="fl" style="margin:0">生成条数:<b id="cntVal">5</b></label>
|
||
<input type="range" id="cntRange" min="1" max="10" value="5" style="max-width:280px">
|
||
</div>
|
||
<div class="field-row">
|
||
<button type="button" class="btn btn-primary" id="btnGen">生成密码</button>
|
||
<button type="button" class="btn" id="btnCopyAll">复制全部</button>
|
||
</div>
|
||
<div id="pwdMsg"></div>
|
||
<div class="pwd-results" id="pwdList"></div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<?php layout_theme_fab(); ?>
|
||
<?php layout_footer(); ?>
|
||
<script src="../assets/js/common.js"></script>
|
||
<script>
|
||
(function () {
|
||
'use strict';
|
||
var SETS = {
|
||
upper: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||
lower: 'abcdefghijklmnopqrstuvwxyz',
|
||
digit: '0123456789',
|
||
sym: '!@#$%^&*()-_=+[]{};:,.<>?'
|
||
};
|
||
|
||
function $(id) { return document.getElementById(id); }
|
||
function uniq(str) {
|
||
var seen = {}, out = '';
|
||
for (var i = 0; i < str.length; i++) {
|
||
var ch = str.charAt(i);
|
||
if (!seen[ch]) { seen[ch] = 1; out += ch; }
|
||
}
|
||
return out;
|
||
}
|
||
function randInt(max) { return Math.floor(Math.random() * max); }
|
||
|
||
function charset() {
|
||
if ($('ckCustom').checked) {
|
||
var c = uniq($('inCustom').value);
|
||
return c;
|
||
}
|
||
var s = '';
|
||
if ($('ckUpper').checked) s += SETS.upper;
|
||
if ($('ckLower').checked) s += SETS.lower;
|
||
if ($('ckDigit').checked) s += SETS.digit;
|
||
if ($('ckSym').checked) s += SETS.sym;
|
||
return uniq(s);
|
||
}
|
||
|
||
function genOne(chars, len) {
|
||
var out = '';
|
||
// 确保自定义字符集大小时每个字符都可能出现
|
||
for (var i = 0; i < len; i++) {
|
||
out += chars.charAt(randInt(chars.length));
|
||
}
|
||
return out;
|
||
}
|
||
|
||
function generate() {
|
||
var chars = charset();
|
||
var len = parseInt($('lenRange').value, 10);
|
||
var cnt = parseInt($('cntRange').value, 10);
|
||
var msg = $('pwdMsg');
|
||
var list = $('pwdList');
|
||
if (!chars) {
|
||
msg.innerHTML = '<div class="err-msg">请至少选择一种字符集,或填写自定义字符集。</div>';
|
||
list.innerHTML = '';
|
||
return;
|
||
}
|
||
if ($('ckCustom').checked && chars.length < 2) {
|
||
msg.innerHTML = '<div class="err-msg">自定义字符集至少包含 2 个不同字符。</div>';
|
||
list.innerHTML = '';
|
||
return;
|
||
}
|
||
msg.innerHTML = '';
|
||
list.innerHTML = '';
|
||
for (var i = 0; i < cnt; i++) {
|
||
var pwd = genOne(chars, len);
|
||
var line = document.createElement('div');
|
||
line.className = 'pwd-line';
|
||
var code = document.createElement('code');
|
||
code.textContent = pwd; // 用 textContent 写入,避免 HTML 注入
|
||
var copyBtn = document.createElement('button');
|
||
copyBtn.type = 'button';
|
||
copyBtn.className = 'btn btn-sm js-copy';
|
||
copyBtn.setAttribute('data-copy', pwd);
|
||
copyBtn.textContent = '复制';
|
||
line.appendChild(code);
|
||
line.appendChild(copyBtn);
|
||
list.appendChild(line);
|
||
}
|
||
}
|
||
|
||
function copyAll() {
|
||
var codes = Array.prototype.slice.call($('pwdList').querySelectorAll('code'));
|
||
var text = codes.map(function (c) { return c.textContent; }).join('\n');
|
||
if (!text) return;
|
||
HomePage.copyText(text, $('btnCopyAll'));
|
||
}
|
||
|
||
$('ckCustom').addEventListener('change', function () {
|
||
var on = $('ckCustom').checked;
|
||
['ckUpper', 'ckLower', 'ckDigit', 'ckSym'].forEach(function (id) {
|
||
$(id).disabled = on;
|
||
});
|
||
});
|
||
$('lenRange').addEventListener('input', function () { $('lenVal').textContent = this.value; });
|
||
$('cntRange').addEventListener('input', function () { $('cntVal').textContent = this.value; });
|
||
$('btnGen').addEventListener('click', generate);
|
||
$('btnCopyAll').addEventListener('click', copyAll);
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|