文章详情

返回首页

CF上的Workers搭建vps计算器等多功能工具箱

分享文章 作者: Ws01 创建时间: 2025-12-09 更新时间: 2025-12-28 📝 字数: 29,946 字 👁️ 阅读: 24 次
CF上的Workers搭建vps计算器等多功能工具箱
addEventListener('fetch', event => {

event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
const html = `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="language" content="zh-CN">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多功能工具箱</title>
<style>
body {
font-family: Arial, sans-serif;
padding: 20px;
background-image: url('https://xxq.dpdns.org/');
background-size: cover;
background-position: center;
height: 100vh;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
.container {
max-width: 500px;
margin: 0 auto;
background-color: rgba(255, 255, 255, 0.4);
padding: 20px;
border-radius: 10px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
}
.container1 {
max-width: 500px;
margin: 0 auto;
background-color: rgba(255, 255, 255, 0.4);
padding: 8px;
border-radius: 6px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
}
h3 {
color: #218838;
text-align: center;
}
h5 {
color: red;
text-align: left;
}
h6 {
background-color: rgba(255, 255, 255, 0.4);
color: red;
text-align: left;
border-radius: 6px;
}
label {
display: block;
margin-bottom: 8px;
color: #333;
}
.row {
display: flex;
justify-content: space-between;
margin-bottom: 15px;
gap: 10px;
}
.field-group {
flex: 1;
display: flex;
flex-direction: column;
}
.field-group label {
margin-bottom: 5px;
}
input, select {
padding: 8px;
border: 1px solid #ccc;
border-radius: 5px;
width: 100%;
box-sizing: border-box;
}
button {
padding: 10px;
background-color: #28a745;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
width: 100%;
}
button:hover {
background-color: #218838;
}
.result {
margin-top: 20px;
padding: 10px;
background-color: #dff0d8;
border: 1px solid #d6e9c6;
color: black;
border-radius: 5px;
}
.sites {
width:410px;
background-color: rgba(211, 211, 211, 0.01);
border:1px solid rgba(0,0,0,.001);
margin:1px auto;
padding:1px;
border-radius: 10px;
}
.sites1 {
width:400px;
background-color: rgba(211, 211, 211, 0.2);
border:1px solid rgba(0,0,0,.02);
margin:1px auto;
padding:1px;
border-radius: 10px;
}
.footer {
color: #333;
width:385px;
height:20px;
text-align:center;
margin:2px auto;
padding:1px;
border-radius: 10px;
}

/ 汇率转换器样式 /
.converter {
background-color: rgba(245, 245, 245,0.2);
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.input-group {
margin-bottom: 15px;
max-width: 440px;
}
.rate-info {
margin: 5px 0;
color: #666;
font-size: 18px;
max-width: 240px;
border-radius: 5px;
background-color: #E6E6FA;
}

/ 密码生成器样式 /
.password {
font-size: 15px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 5px;
background-color: rgba(211, 211, 211, 0.6);
margin-top: 20px;
min-width: 100px;
max-width: 340px;
min-height: 48px;
text-align: left;
white-space: pre-line;
}
.button-container {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
}
.button-container button {
margin: 0 6px;
font-size: 14px;
}
.option-row {
display: flex;
justify-content: space-between;
width: 340px;
margin-bottom: 12px;
}
// 修改标签样式,减小字体大小并防止换行
label {
font-size: 16px;
display: flex;
align-items: center;
width: 48%;
white-space: nowrap;
}
input[type=checkbox] {
transform: scale(1.5);
margin-left: 10px;
}
.progress-bar {
height: 20px;
width: 100%;
background: #ddd;
border-radius: 10px;
overflow: hidden;
margin-bottom: 10px;
}
.progress {
height: 100%;
width: 0%;
transition: width 0.3s ease;
}
.score {
font-weight: bold;
margin-top: 10px;
}
.advice {
margin-top: 15px;
text-align: left;
font-size: 14px;
background-color: rgba(255, 255, 255, 0.7);
padding: 10px;
border-radius: 5px;
}

/ 导航按钮 - 固定在顶部 /
.nav-buttons {
position: fixed;
top: 0;
left: 50%;
transform: translateX(-50%);
display: flex;
justify-content: center;
margin-bottom: 20px;
z-index: 1000;
background-color: rgba(255, 255, 255, 0.9);
padding: 10px;
border-radius: 0 0 10px 10px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
width: 410px;
}
.nav-button {
padding: 10px 20px;
margin: 0 5px;
background-color: #6c757d;
border: none;
border-radius: 5px;
color: white;
cursor: pointer;
}
.nav-button.active {
background-color: #28a745;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}

/ 为内容区域添加顶部边距,避免被固定的导航按钮遮挡 /
#page-title {
margin-top: 60px;
}
</style>
</head>
<body>
<div class="sites">
<div class="nav-buttons">
<button class="nav-button active" onclick="showTab('vps')">📅VPS计算器</button>
<button class="nav-button" onclick="showTab('exchange')">📅汇率转换</button>
<button class="nav-button" onclick="showTab('password')">🔐密码生成</button>
</div>

<h3 id="page-title">📅VPS剩余价值计算器</h3>
<h6>⚡mjj祖训:一邮一鸡!不买实名鸡、高溢价鸡和LXC小鸡,慎买预售鸡。</h6>

<div class="sites1">
<!-- VPS 计算器 -->
<div id="vps-tab" class="tab-content active">
<div class="container">
<form id="calculator-form">
<div class="row">
<div class="field-group">
<label for="currency">货币种类</label>
<select id="currency" required onchange="updateExchangeRate()">
<option value="CNY">¥人民币 (CNY)</option>
<option value="USD" selected>$美元 (USD)</option>
<option value="EUR">€欧元 (EUR)</option>
<option value="GBP">£英镑 (GBP)</option>
<option value="CAD">$加拿大元 (CAD)</option>
<option value="AUD">$澳元 (AUD)</option>
<option value="JPY">¥日元 (JPY)</option>
<option value="SGD">S$新加坡元 (SGD)</option>
<option value="KRW">₩韩元 (KRW)</option>
<option value="HKD">HK$港币 (HKD)</option>
<option value="TWD">NT$新台币 (TWD)</option>
</select>
</div>
<div class="field-group">
<label for="exchangeRate">今日汇率</label>
<input type="text" id="exchangeRate" value="1" readonly>
</div>
</div>
<div class="row">
<div class="field-group">
<label for="purchaseDate">购买日期</label>
<input type="date" id="purchaseDate" value="${new Date().toISOString().slice(0, 10)}" required>
</div>
<div class="field-group">
<label for="paymentCycle">付款周期</label>
<select id="paymentCycle" required>
<option value="monthly">1月付(Monthly)</option>
<option value="quarterly">1季付(Quarterly)</option>
<option value="semiannually">半年付(Semi-annually)</option>
<option value="yearly" selected>1年付(Yearly)</option>
<option value="biennially">2年付(Biennially)</option>
<option value="triennially">3年付(Triennially)</option>
</select>
</div>
</div>
<div class="row">
<div class="field-group">
<label for="renewalAmount">续费金额</label>
<input type="number" id="renewalAmount" placeholder="请输入续费金额" required>
</div>
<div class="field-group">
<label for="purchaseAmount">购买金额</label>
<input type="number" id="purchaseAmount" placeholder="请输入购买金额" required>
</div>
</div>
<div class="row">
<div class="field-group">
<label for="expiryDate">续费日期</label>
<input type="date" id="expiryDate" required>
</div>
<div class="field-group">
<label>&nbsp;</label>
<button type="button" onclick="calculate()">📅计算</button>
</div>
</div>
</form>
<div id="result" class="result" style="display:none;"></div>
</div>
</div>

<!-- 汇率转换器 -->
<div id="exchange-tab" class="tab-content">
<div class="converter">
<div class="input-group">
<label for="currency-exchange">选择货币:</label>
<select id="currency-exchange">
<option value="USD" selected>美元 (USD)</option>
<option value="CNY">人民币 (CNY)</option>
<option value="EUR">欧元 (EUR)</option>
<option value="GBP">英镑 (GBP)</option>
<option value="JPY">日元 (JPY)</option>
<option value="SGD">新加坡元 (SGD)</option>
<option value="HKD">港币 (HKD)</option>
<option value="CAD">加拿大元 (CAD)</option>
<option value="AUD">澳大利亚元 (AUD)</option>
<option value="KRW">韩元 (KRW)</option>
<option value="TWD">新台币 (TWD)</option>
<option value="VND">越南盾 (VND)</option>
<option value="RUB">俄罗斯卢布 (RUB)</option>
<option value="MMK">缅甸元 (MMK)</option>
<option value="CHF">瑞士法郎 (CHF)</option>
<option value="INR">印度卢比 (INR)</option>
<option value="PKR">巴基斯坦卢比 (PKR)</option>
<option value="ANG">荷兰盾 (ABG)</option>
<option value="ARS">阿根廷比索 (ARS)</option>
<option value="UAH">乌克兰格里夫纳 (UAH)</option>
</select>
</div>

<div class="input-group">
<label for="amount-exchange">输入金额:</label>
<input type="number" id="amount-exchange" placeholder="输入要转换的金额" value="1">
</div>

<div class="input-group">
<label for="targetCurrency-exchange">目标货币:</label>
<select id="targetCurrency-exchange">
<option value="USD">美元 (USD)</option>
<option value="CNY" selected>人民币 (CNY)</option>
<option value="EUR">欧元 (EUR)</option>
<option value="GBP">英镑 (GBP)</option>
<option value="JPY">日元 (JPY)</option>
<option value="SGD">新加坡元 (SGD)</option>
<option value="HKD">港币 (HKD)</option>
<option value="CAD">加拿大元 (CAD)</option>
<option value="AUD">澳大利亚元 (AUD)</option>
<option value="KRW">韩元 (KRW)</option>
<option value="TWD">新台币 (TWD)</option>
<option value="VND">越南盾 (VND)</option>
<option value="RUB">俄罗斯卢布 (RUB)</option>
<option value="MMK">缅甸元 (K)</option>
<option value="CHF">瑞士法郎 (CHF)</option>
<option value="INR">印度卢比 (INR)</option>
<option value="PKR">巴基斯坦卢比 (PKR)</option>
<option value="ANG">荷兰盾 (ABG)</option>
<option value="ARS">阿根廷比索 (ARS)</option>
<option value="UAH">乌克兰格里夫纳 (UAH)</option>
</select>
<div class="rate-info" id="rateInfo-exchange"></div>
</div>

<button onclick="convertCurrency()">点击转换</button>
<div class="result" id="result-exchange">结果将在这里显示</div>
</div>
</div>

<!-- 密码生成器 -->
<div id="password-tab" class="tab-content">
<div class="container">
<div class="option-row">
<label>大写(A-Z) <input type="checkbox" id="includeUppercase" checked></label>
<label>小写(a-z) <input type="checkbox" id="includeLowercase" checked></label>
</div>
<div class="option-row">
<label>数字(0-9) <input type="checkbox" id="includeNumbers" checked></label>
<label>排除l10o <input type="checkbox" id="excludeCharacters"></label>
</div>
<div class="option-row">
<label>部份字符 <input type="checkbox" id="includeSpecial1"></label>
<label>全部字符 <input type="checkbox" id="includeSpecial2"></label>
</div>
<div class="option-row">
<label for="passwordCount">生成个数 <input type="number" id="passwordCount" value="1" min="1" max="10"></label>
<label for="passwordLength">密码长度 <input type="number" id="passwordLength" value="16" min="6" max="32"></label>
</div>

<!-- 生成密码、UUID和复制按钮 -->
<div class="button-container">
<button onclick="generatePassword()">生成密码</button>
<button onclick="generateUUIDs()">生成UUID</button>
<button onclick="copyPassword()">复制</button>
</div>
<div class="password" id="passwordDisplay"></div>
<div class="progress-bar"><div class="progress" id="progress"></div></div>
<div class="score" id="score">安全得分: 0 / 100</div>
<div class="advice" id="advice"></div>
</div>
</div>

<!-- 页脚 -->
<div class="container1">
<div class="footer">
<span id="timeDate">载入天数...</span>
<script>
var now = new Date();
function createtime() {
var grt = new Date("11/11/2024 00:00:00");
now.setTime(now.getTime() + 250);
var days = (now - grt) / 1000 / 60 / 60 / 24;
var dnum = Math.floor(days);
document.getElementById("timeDate").innerHTML = "稳定运行" + dnum + "天";
}
setInterval(createtime, 250);
</script>
<span> | 总访问量 <span id="busuanzisitepv"></span> 次
<a href="https://boke.199881.xyz/" target="_blank">
<span style="color: green;">博客</span>
</a>
</span>
<script defer src="https://bsz.211119.xyz/js"></script>
</div>
</div>
</div>
</div>

<!-- 主脚本 -->
<script>
// 切换标签页
function showTab(tabName) {
// 隐藏所有标签页内容
document.querySelectorAll('.tab-content').forEach(tab => {
tab.classList.remove('active');
});

// 移除所有导航按钮的活动状态
document.querySelectorAll('.nav-button').forEach(button => {
button.classList.remove('active');
});

// 显示选中的标签页
document.getElementById(tabName + '-tab').classList.add('active');

// 设置活动状态的导航按钮
event.target.classList.add('active');

// 更新页面标题
const titles = {
'vps': '📅VPS剩余价值计算器',
'exchange': '📅汇率转换器',
'password': '🔐密码和UUID生成器'
};
document.getElementById('page-title').textContent = titles[tabName];
}

// VPS 计算器相关函数
const exchangeCache = {};

async function fetchExchangeRate(fromCurrency, toCurrency) {
const cacheKey = fromCurrency + "_" + toCurrency;
if (exchangeCache[cacheKey]) return exchangeCache[cacheKey];

try {
const response = await fetch(\https://open.er-api.com/v6/latest/\${fromCurrency}\);
const data = await response.json();
const rate = data.rates[toCurrency];
if (rate) {
exchangeCache[cacheKey] = rate;
return rate;
}
} catch (error) {
console.error('获取汇率时出错:', error);
}
return null;
}

async function updateExchangeRate() {
const currency = document.getElementById('currency').value;
const exchangeRate = await fetchExchangeRate(currency, 'CNY');
document.getElementById('exchangeRate').value = exchangeRate ? exchangeRate.toFixed(2) : '获取失败';
}

window.onload = updateExchangeRate;

async function calculate() {
const purchaseAmount = parseFloat(document.getElementById('purchaseAmount').value);
const renewalAmount = parseFloat(document.getElementById('renewalAmount').value);
const currency = document.getElementById('currency').value;
const exchangeRateToCNY = await fetchExchangeRate(currency, 'CNY');

if (!exchangeRateToCNY) {
document.getElementById('result').innerHTML = '获取汇率时出错,请稍后再试。';
document.getElementById('result').style.display = 'block';
return;
}

const paymentCycle = document.getElementById('paymentCycle').value;
const purchaseDate = new Date(document.getElementById('purchaseDate').value);
const expiryDate = new Date(document.getElementById('expiryDate').value);
const today = new Date();

if (expiryDate <= purchaseDate) {
document.getElementById('result').innerHTML = '续费日期应晚于购买日期。';
document.getElementById('result').style.display = 'block';
return;
}

const totalDays = Math.floor((expiryDate - today) / (1000 60 60 * 24));
if (totalDays <= 0) {
document.getElementById('result').innerHTML = 'VPS已过期。';
document.getElementById('result').style.display = 'block';
return;
}

const cycleMap = {
'monthly': 30,
'quarterly': 90,
'semiannually': 180,
'yearly': 365,
'biennially': 730,
'triennially': 1095
};

const cycleDays = cycleMap[paymentCycle] || 30;
const remainingValue = (totalDays / cycleDays) * renewalAmount;
const remainingValueCNY = remainingValue * exchangeRateToCNY;
const premiumAmount = purchaseAmount - remainingValueCNY;

let suggestion = '';
if (premiumAmount >= 200) suggestion = '重要的话说三遍,不要买,不要买,不要买。';
else if (premiumAmount >= 100) suggestion = '特超高溢价,不要买,不要买。';
else if (premiumAmount >= 50) suggestion = '超高溢价,不要买。';
else if (premiumAmount >= 20) suggestion = '高溢价,再想想。';
else if (premiumAmount >= 5) suggestion = '小溢价,想想。';
else if (premiumAmount >= 0) suggestion = '超小溢价,不用想。';
else if (premiumAmount >= -20) suggestion = '卖家小亏,需要就买。';
else if (premiumAmount >= -50) suggestion = '卖家大亏,可以买!';
else if (premiumAmount >= -100) suggestion = '卖家血亏,抓紧买!!';
else if (premiumAmount >= -200) suggestion = '卖家大出血,立刻买!!!';
else suggestion = '不得了,卖家大出血,闭眼买!!!';

document.getElementById('result').innerHTML = \`
<strong>⌚剩余天数:</strong> \${totalDays} 天<br>
<strong>💰续费金额:</strong> \${(renewalAmount * exchangeRateToCNY).toFixed(2)} ¥<br>
<strong>➖剩余价值:</strong> \${remainingValueCNY.toFixed(2)} ¥<br>
<strong>➕溢价金额:</strong> \${premiumAmount.toFixed(2)} ¥<br>
<strong>🎤购买建议:</strong> \${suggestion}<br>
\`;
document.getElementById('result').style.display = 'block';
}

// 汇率转换器相关函数
document.getElementById('amount-exchange').addEventListener('input', convertCurrency);
document.getElementById('currency-exchange').addEventListener('change', convertCurrency);
document.getElementById('targetCurrency-exchange').addEventListener('change', convertCurrency);

async function convertCurrency() {
const currency = document.getElementById('currency-exchange').value;
const targetCurrency = document.getElementById('targetCurrency-exchange').value;
const amount = parseFloat(document.getElementById('amount-exchange').value);

if (isNaN(amount)) {
document.getElementById('result-exchange').innerHTML = '请输入有效的金额';
return;
}

try {
const response = await fetch(\https://api.exchangerate-api.com/v4/latest/\${currency}\);
const data = await response.json();
const rate = data.rates[targetCurrency];

if (rate) {
const result = amount * rate;
document.getElementById('rateInfo-exchange').innerHTML =
'汇率: 1 ' + currency + ' = ' + rate + ' ' + targetCurrency;
document.getElementById('result-exchange').innerHTML =
amount + ' ' + currency + ' = ' + result.toFixed(2) + ' ' + targetCurrency;
} else {
// 如果主API没有目标货币,则尝试备用API
const resp2 = await fetch(\https://womjj.deno.dev/rate?fsym=\${currency}&tsym=\${targetCurrency}\);
const obj = await resp2.json();
const backupRate = obj[targetCurrency] || obj['CNY'];

if (backupRate) {
const result = amount * backupRate;
document.getElementById('rateInfo-exchange').innerHTML =
'汇率: 1 ' + currency + ' = ' + backupRate + ' ' + targetCurrency;
document.getElementById('result-exchange').innerHTML =
amount + ' ' + currency + ' = ' + result.toFixed(2) + ' ' + targetCurrency;
} else {
document.getElementById('result-exchange').innerHTML = '无法获取汇率信息';
}
}
} catch (error) {
document.getElementById('result-exchange').innerHTML = '获取汇率失败,请稍后再试';
document.getElementById('rateInfo-exchange').innerHTML = '';
console.error('汇率获取失败:', error);
}
}

// 密码生成器相关函数
function generatePassword() {
const length = document.getElementById('passwordLength').value;
const count = document.getElementById('passwordCount').value;
const includeUppercase = document.getElementById('includeUppercase').checked;
const includeLowercase = document.getElementById('includeLowercase').checked;
const includeNumbers = document.getElementById('includeNumbers').checked;
const includeSpecial1 = document.getElementById('includeSpecial1').checked;
const includeSpecial2 = document.getElementById('includeSpecial2').checked;
const excludeCharacters = document.getElementById('excludeCharacters').checked;

let charset = '';
if (includeUppercase) charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (includeLowercase) charset += 'abcdefghijklmnopqrstuvwxyz';
if (includeNumbers) charset += '0123456789';
if (includeSpecial1) charset += '!#$%^&*_<>';
if (includeSpecial2) charset += '!@#$%^&*()_+{}|:<>?-=[];,./';

if (excludeCharacters) {
charset = charset.replace(/[iIl10oO]/g, '');
}

let passwords = [];
for (let j = 0; j < count; j++) {
let password = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * charset.length);
password += charset[randomIndex];
}
passwords.push(password);
}

document.getElementById('passwordDisplay').textContent = passwords.join('\\n');

// 只检测第一个密码的安全性
if (passwords.length > 0) {
const result = evaluatePassword(passwords[0]);
document.getElementById('score').innerText = \安全得分: \${result.score} / 100\;
document.getElementById('progress').style.width = \\${result.score}%\;
document.getElementById('progress').style.background = getColor(result.score);
document.getElementById('advice').innerHTML = result.advice;
}
}

function copyPassword() {
const passwordDisplay = document.getElementById('passwordDisplay');
const password = passwordDisplay.textContent;

const tempInput = document.createElement('textarea');
tempInput.value = password;
document.body.appendChild(tempInput);

tempInput.select();
document.execCommand('copy');
document.body.removeChild(tempInput);

alert('Password copied to clipboard!');
}

function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}

function generateUUIDs() {
const count = document.getElementById('passwordCount').value;
let uuids = [];
for (let i = 0; i < count; i++) {
uuids.push(generateUUID());
}
document.getElementById('passwordDisplay').textContent = uuids.join('\\n');

// 生成UUID时清除安全性检测结果
document.getElementById('score').innerText = '安全得分: 0 / 100';
document.getElementById('progress').style.width = '0%';
document.getElementById('advice').innerHTML = '';
}

function evaluatePassword(password) {
let score = 0;
let advice = '';
const length = password.length;

let hasLower = /[a-z]/.test(password);
let hasUpper = /[A-Z]/.test(password);
let hasDigit = /\\d/.test(password);
let hasSpecial = /[^a-zA-Z0-9]/.test(password);

let typeCount = 0;
if (hasLower) score += 5, typeCount++;
if (hasDigit) score += 5, typeCount++;
if (hasUpper) score += 10, typeCount++;
if (hasSpecial) score += 20, typeCount++;

// 字符重复限制处理
let repeatCount = 1;
let lastChar = '';
let bonusLength = 0;

for (let i = 0; i < password.length; i++) {
const char = password[i];
if (char === lastChar) {
repeatCount++;
} else {
repeatCount = 1;
lastChar = char;
}

if (i >= 6) { // 第7个字符起计入加分
if (repeatCount <= 3) {
bonusLength += 1;
}
}
}

let lengthBonus = Math.min(bonusLength * 4, 60);
score += lengthBonus;

const includedTypes = [];
if (hasDigit) includedTypes.push('数字');
if (hasLower) includedTypes.push('小写字母');
if (hasUpper) includedTypes.push('大写字母');
if (hasSpecial) includedTypes.push('特殊字符');

advice += \包含:\${includedTypes.join('、')},有 \${length} 位。<br><br>\;

// 提示建议
if (typeCount < 2) {
advice += "建议至少包含两种字符类型(如字母+数字)。<br><br>";
}
if (length < 8) {
advice += "密码长度建议至少为 8 位。<br><br>";
}

if (score < 20) {
advice += "️⚠️特弱,必须提升安全性,建议至少使用大小写字母、数字和特殊字符。<br><br>";
} else if (score < 40) {
advice += "⚠️弱,必须加强,可考虑增加长度或多样性。<br><br>";
} else if (score < 60) {
advice += "🛡️一般,必须进一步加强。<br><br>";
} else if (score < 80) {
advice += "️🛡️勉强可以,进一步加强。<br><br>";
} else if (score < 90) {
advice += "🔒安全!可进一步加强。<br><br>";
} else {
advice += "🔒非常安全!请定期更换。<br><br>";
}

// 估算破解时间
const timeEstimate = estimateCrackTime(password, typeCount);
advice += \估计暴力破解时间:<strong>\${timeEstimate}</strong>\;

return { score: Math.min(score, 100), advice };
}

function getColor(score) {
if (score < 20) return '#e74c3c'; // red
if (score < 40) return '#ff9900'; // #ff9900
if (score < 60) return '#66CDAA'; // #66CDAA
if (score < 80) return '#7CCD7C'; // #7CCD7C
if (score < 90) return '#27ae60'; // #27ae60
return 'green'; // green
}

function estimateCrackTime(password, typeCount) {
let charsetSize = 0;
if (/[a-z]/.test(password)) charsetSize += 26;
if (/[A-Z]/.test(password)) charsetSize += 26;
if (/\\d/.test(password)) charsetSize += 10;
if (/[^a-zA-Z0-9]/.test(password)) charsetSize += 32;

const combinations = BigInt(charsetSize) BigInt(password.length);
const guessesPerSecond = 1000000_00n; // 1 亿次/秒
const averageGuesses = combinations / 2n;
const seconds = averageGuesses / guessesPerSecond;

return formatTime(seconds);
}

function formatTime(seconds) {
const s = Number(seconds);
if (s < 60) return \\${Math.round(s)} 秒\;
if (s < 3600) return \\${Math.round(s / 60)} 分钟\;
if (s < 86400) return \\${Math.round(s / 3600)} 小时\;
if (s < 31536000) return \\${Math.round(s / 86400)} 天\;
const years = s / 31536000;
if (years < 10000) return \\${Math.round(years)} 年\;
if (years < 100000000) return \\${(years / 10000).toFixed(1)} 万年\;
if (years < 10000000000) return \\${(years / 100000000).toFixed(1)} 亿年\;
if (years < 1000000000000) return \\${(years / 10000000000).toFixed(1)} 百亿年\;
if (years < 1000000000000) return \\${(years / 100000000000).toFixed(1)} 千亿年\;
if (years < 1000000000000) return \\${(years / 1000000000000).toFixed(1)} 万亿年\;
return \超过 \${Math.round(years / 10000000000000)} 兆亿年\;
}
</script>
</body>
</html>`;

return new Response(html, {
headers: { "content-type": "text/html;charset=UTF-8" },
});
}