4位PIN穷举助手
by 孙 超
HTML
<div id="pin">0000</div>
<div id="count"></div>
<div>
<button id="prevBtn">上一个</button>
<button id="nextBtn">下一个(空格)</button>
</div>
<h3>随机生成记录</h3>
<div id="history"></div>
<h3>导入已试过数字</h3>
<textarea id="batchInput" placeholder="每行输入一个4位数字"></textarea>
<br />
<button id="importBtn">导入</button>
<div id="tip">按 空格 键切换下一个未试过的4位数字</div>
CSS
body {
font-family: sans-serif;
text-align: center;
padding: 40px;
}
#pin {
font-size: 90px;
font-weight: bold;
letter-spacing: 10px;
margin-bottom: 10px;
}
#count {
font-size: 18px;
color: #666;
margin-bottom: 20px;
}
#history {
margin: 20px auto;
width: 320px;
text-align: left;
border: 1px solid #ccc;
padding: 10px;
max-height: 220px;
overflow-y: auto;
font-family: monospace;
background: #fafafa;
}
textarea {
width: 320px;
height: 180px;
font-size: 16px;
padding: 10px;
margin-top: 20px;
}
button {
margin-top: 10px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
#tip {
margin-top: 30px;
color: #999;
}
JavaScript
/**
* 已经尝试过的密码:
* 1.日期 0101到1231
* 2. 1900到2056
* 3. 9800~9899,9900~9999
*
*
*
*/
const GENERATED_KEY = 'generatedPins';
const IMPORTED_KEY = 'importedPins';
let generatedPins = JSON.parse(
localStorage.getItem(GENERATED_KEY) || '[]'
);
let importedPins = new Set(
JSON.parse(localStorage.getItem(IMPORTED_KEY) || '[]')
);
let currentIndex = generatedPins.length - 1;
const pinEl = document.getElementById('pin');
const countEl = document.getElementById('count');
const historyEl = document.getElementById('history');
const batchInput = document.getElementById('batchInput');
function save() {
localStorage.setItem(
GENERATED_KEY,
JSON.stringify(generatedPins)
);
localStorage.setItem(
IMPORTED_KEY,
JSON.stringify([...importedPins])
);
}
function getAllTestedSet() {
return new Set([
...generatedPins,
...importedPins
]);
}
function updateCount() {
const total = getAllTestedSet().size;
countEl.innerText =
`总已尝试: ${total} / 10000
随机生成: ${generatedPins.length}
手动导入: ${importedPins.size}`;
}
function updateHistory() {
historyEl.innerHTML =
generatedPins
.slice()
.reverse()
.map((v, i) => {
const realIndex =
generatedPins.length - 1 - i;
const mark =
realIndex === currentIndex
? '👉 '
: '';
return `<div>${mark}${v}</div>`;
})
.join('');
}
function showCurrent() {
if (
currentIndex >= 0 &&
currentIndex < generatedPins.length
) {
pinEl.innerText =
generatedPins[currentIndex];
}
updateHistory();
updateCount();
}
function generateNextPin() {
const tested = getAllTestedSet();
if (tested.size >= 10000) {
pinEl.innerText = 'DONE';
return;
}
let pin;
do {
pin = Math.floor(Math.random() * 10000)
.toString()
.padStart(4,...