文章详情

返回首页

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

分享文章 作者: Ws01 创建时间: 2025-12-09 📝 字数: 29,904 字 👁️ 阅读: 13 次

原始 Markdown

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="busuanzi_site_pv"></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 = 1_000_000_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" },
  });
}

预览

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" }, }); }