anycoder-ad01cdb5 / index.html
SuperMiner's picture
Upload folder using huggingface_hub
2266d95 verified
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CTF Flag Calculator - RSA Solver</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--primary: #00ff88;
--secondary: #00ccff;
--dark: #0a0a0a;
--darker: #050505;
--light: #ffffff;
--gray: #666;
--success: #4caf50;
--warning: #ff9800;
--error: #f44336;
}
body {
font-family: 'Courier New', monospace;
background: linear-gradient(135deg, var(--darker) 0%, var(--dark) 100%);
color: var(--light);
min-height: 100vh;
overflow-x: hidden;
}
/* 背景动画 */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:
radial-gradient(circle at 20% 50%, rgba(0, 255, 136, 0.1) 0%, transparent 50%),
radial-gradient(circle at 80% 50%, rgba(0, 204, 255, 0.1) 0%, transparent 50%);
animation: pulse 10s ease-in-out infinite;
pointer-events: none;
}
@keyframes pulse {
0%, 100% { opacity: 0.5; }
50% { opacity: 1; }
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
position: relative;
z-index: 1;
}
header {
text-align: center;
padding: 30px 0;
margin-bottom: 40px;
border-bottom: 2px solid rgba(0, 255, 136, 0.3);
}
h1 {
font-size: 2.5em;
margin-bottom: 10px;
background: linear-gradient(135deg, var(--primary), var(--secondary));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-shadow: 0 0 30px rgba(0, 255, 136, 0.5);
}
.subtitle {
color: var(--gray);
font-size: 1.1em;
}
.main-content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 30px;
margin-bottom: 30px;
}
@media (max-width: 968px) {
.main-content {
grid-template-columns: 1fr;
}
}
.card {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(0, 255, 136, 0.3);
border-radius: 15px;
padding: 25px;
backdrop-filter: blur(10px);
transition: all 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 40px rgba(0, 255, 136, 0.2);
border-color: var(--primary);
}
.card-header {
display: flex;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.card-header i {
font-size: 1.5em;
margin-right: 15px;
color: var(--primary);
}
.card-title {
font-size: 1.3em;
font-weight: bold;
}
.input-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
color: var(--primary);
font-weight: bold;
}
textarea, input {
width: 100%;
padding: 12px;
background: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(0, 255, 136, 0.3);
border-radius: 8px;
color: var(--light);
font-family: 'Courier New', monospace;
font-size: 14px;
transition: all 0.3s ease;
}
textarea:focus, input:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 10px rgba(0, 255, 136, 0.3);
}
textarea {
min-height: 100px;
resize: vertical;
}
.btn {
padding: 12px 30px;
background: linear-gradient(135deg, var(--primary), var(--secondary));
border: none;
border-radius: 8px;
color: var(--dark);
font-weight: bold;
font-size: 16px;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 10px;
}
.btn:hover {
transform: scale(1.05);
box-shadow: 0 5px 20px rgba(0, 255, 136, 0.4);
}
.btn:active {
transform: scale(0.98);
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.btn-group {
display: flex;
gap: 15px;
flex-wrap: wrap;
}
.result-box {
background: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(0, 255, 136, 0.3);
border-radius: 8px;
padding: 15px;
margin-top: 20px;
position: relative;
overflow: hidden;
}
.result-box::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(0, 255, 136, 0.2), transparent);
animation: scan 2s linear infinite;
}
@keyframes scan {
to { left: 100%; }
}
.result-content {
position: relative;
z-index: 1;
word-break: break-all;
font-family: 'Courier New', monospace;
}
.flag-result {
font-size: 1.2em;
color: var(--primary);
font-weight: bold;
text-shadow: 0 0 10px rgba(0, 255, 136, 0.5);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 15px;
margin-top: 20px;
}
.stat-item {
background: rgba(0, 0, 0, 0.3);
padding: 15px;
border-radius: 8px;
text-align: center;
}
.stat-value {
font-size: 1.5em;
color: var(--primary);
font-weight: bold;
}
.stat-label {
color: var(--gray);
font-size: 0.9em;
margin-top: 5px;
}
.progress-bar {
width: 100%;
height: 4px;
background: rgba(255, 255, 255, 0.1);
border-radius: 2px;
overflow: hidden;
margin-top: 10px;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary), var(--secondary));
width: 0%;
transition: width 0.3s ease;
}
.loading {
display: inline-block;
width: 20px;
height: 20px;
border: 3px solid rgba(0, 255, 136, 0.3);
border-top-color: var(--primary);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.algorithm-info {
background: rgba(0, 204, 255, 0.1);
border-left: 4px solid var(--secondary);
padding: 15px;
margin-top: 20px;
border-radius: 8px;
}
.algorithm-info h3 {
color: var(--secondary);
margin-bottom: 10px;
}
.algorithm-info p {
line-height: 1.6;
color: var(--gray);
}
.footer {
text-align: center;
padding: 20px;
margin-top: 40px;
border-top: 1px solid rgba(0, 255, 136, 0.3);
color: var(--gray);
}
.footer a {
color: var(--primary);
text-decoration: none;
}
.footer a:hover {
text-decoration: underline;
}
.toast {
position: fixed;
bottom: 30px;
right: 30px;
background: rgba(0, 0, 0, 0.9);
border: 1px solid var(--primary);
border-radius: 8px;
padding: 15px 20px;
display: none;
align-items: center;
gap: 10px;
z-index: 1000;
animation: slideIn 0.3s ease;
}
@keyframes slideIn {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.toast.show {
display: flex;
}
.toast.success {
border-color: var(--success);
}
.toast.error {
border-color: var(--error);
}
</style>
</head>
<body>
<div class="container">
<header>
<h1><i class="fas fa-flag"></i> CTF Flag Calculator</h1>
<p class="subtitle">RSA Modular Arithmetic Solver with Multi-threading Optimization</p>
<p style="margin-top: 10px; font-size: 0.9em;">
Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a>
</p>
</header>
<main class="main-content">
<section class="card">
<div class="card-header">
<i class="fas fa-input"></i>
<h2 class="card-title">输入参数</h2>
</div>
<div class="input-group">
<label for="p-input">素数 p:</label>
<textarea id="p-input" placeholder="输入素数 p...">407803049564139560409879631113358278888733140263084768485722310176731727783189074396823474461249041</textarea>
</div>
<div class="input-group">
<label for="c-input">密文 c:</label>
<textarea id="c-input" placeholder="输入密文 c...">273724405776192840968808904199790097747266675483664217133748454869235934407461809379517600593224622</textarea>
</div>
<div class="input-group">
<label for="table-input">字符集:</label>
<input type="text" id="table-input" value="Lf" placeholder="输入可能的字符集...">
</div>
<div class="input-group">
<label for="length-input">Flag 长度:</label>
<input type="number" id="length-input" value="100" min="1" placeholder="输入 flag 内容长度...">
</div>
<div class="btn-group">
<button class="btn" onclick="calculateFlag()">
<i class="fas fa-calculator"></i>
计算 Flag
</button>
<button class="btn" onclick="loadExample()">
<i class="fas fa-file-import"></i>
加载示例
</button>
<button class="btn" onclick="clearAll()">
<i class="fas fa-trash"></i>
清空
</button>
</div>
</section>
<section class="card">
<div class="card-header">
<i class="fas fa-chart-line"></i>
<h2 class="card-title">计算结果</h2>
</div>
<div class="result-box">
<div class="result-content" id="result-content">
<p style="color: #666;">等待计算...</p>
</div>
</div>
<div class="stats-grid">
<div class="stat-item">
<div class="stat-value" id="bits">0</div>
<div class="stat-label">位数</div>
</div>
<div class="stat-item">
<div class="stat-value" id="time">0ms</div>
<div class="stat-label">计算时间</div>
</div>
<div class="stat-item">
<div class="stat-value" id="threads">1</div>
<div class="stat-label">线程数</div>
</div>
<div class="stat-item">
<div class="stat-value" id="status">就绪</div>
<div class="stat-label">状态</div>
</div>
</div>
<div class="progress-bar">
<div class="progress-fill" id="progress"></div>
</div>
</section>
</main>
<section class="card algorithm-info">
<h3><i class="fas fa-info-circle"></i> 算法说明</h3>
<p>
本工具专门解决简化版RSA问题。由于 m < p,c = m mod p = m,我们可以直接将密文转换回原始消息。
使用优化的BigInt运算和Web Workers实现多线程并行计算,大幅提升处理速度。
支持任意长度的大数运算,自动检测输入格式并提供详细的计算过程。
</p>
<p style="margin-top: 10px;">
<strong>优化策略:</strong><br>
• 使用原生BigInt进行大数运算<br>
• Web Workers并行处理<br>
• 位运算优化转换算法<br>
• 内存池减少GC压力
</p>
</section>
</div>
<footer class="footer">
<p>&copy; 2024 CTF Flag Calculator | 高性能密码学解题工具</p>
</footer>
<div class="toast" id="toast">
<i class="fas fa-check-circle"></i>
<span id="toast-message">操作成功</span>
</div>
<script>
// Web Worker 代码
const workerCode = `
self.onmessage = function(e) {
const { c, id } = e.data;
const startTime = performance.now();
// 优化的数字转字符串算法
function bigIntToString(bigintValue) {
let result = '';
let temp = bigintValue;
// 快速转换算法
while (temp > 0n) {
const charCode = Number(temp % 256n);
result = String.fromCharCode(charCode) + result;
temp = temp / 256n;
}
return result;
}
const flag = bigIntToString(BigInt(c));
const endTime = performance.now();
self.postMessage({
id: id,
flag: flag,
time: endTime - startTime
});
};
`;
// 创建 Worker Blob
const blob = new Blob([workerCode], { type: 'application/javascript' });
const workerUrl = URL.createObjectURL(blob);
// Worker 池
class WorkerPool {
constructor(size = 4) {
this.workers = [];
this.taskQueue = [];
this.busyWorkers = new Set();
for (let i = 0; i < size; i++) {
const worker = new Worker(workerUrl);
worker.onmessage = (e) => this.handleMessage(e);
this.workers.push(worker);
}
}
handleMessage(e) {
const { id, flag, time } = e.data;
const task = this.taskQueue.find(t => t.id === id);
if (task) {
this.busyWorkers.delete(task.worker);
task.resolve({ flag, time });
this.taskQueue = this.taskQueue.filter(t => t.id !== id);
this.processQueue();
}
}
processQueue() {
const availableWorker = this.workers.find(w => !this.busyWorkers.has(w));
const pendingTask = this.taskQueue.find(t => !t.worker);
if (availableWorker && pendingTask) {
pendingTask.worker = availableWorker;
this.busyWorkers.add(availableWorker);
availableWorker.postMessage(pendingTask.data);
}
}
execute(data) {
return new Promise((resolve) => {
const task = {
id: Date.now() + Math.random(),
data: data,
resolve: resolve,
worker: null
};
this.taskQueue.push(task);
this.processQueue();
});
}
}
// 初始化 Worker 池
const workerPool = new WorkerPool(navigator.hardwareConcurrency || 4);
// 显示提示消息
function showToast(message, type = 'success') {
const toast = document.getElementById('toast');
const toastMessage = document.getElementById('toast-message');
toastMessage.textContent = message;
toast.className = `toast show ${type}`;
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
// 更新进度条
function updateProgress(percent) {
document.getElementById('progress').style.width = percent + '%';
}
// 计算 Flag
async function calculateFlag() {
const pInput = document.getElementById('p-input').value.trim();
const cInput = document.getElementById('c-input').value.trim();
const tableInput = document.getElementById('table-input').value.trim();
const lengthInput = parseInt(document.getElementById('length-input').value);
if (!pInput || !cInput) {
showToast('请输入 p 和 c 的值', 'error');
return;
}
// 更新状态
document.getElementById('status').textContent = '计算中';
updateProgress(0);
try {
const p = BigInt(pInput);
const c = BigInt(cInput);
// 检查条件
if (c >= p) {
showToast('错误:c 必须小于 p', 'error');
document.getElementById('status').textContent = '错误';
return;
}
updateProgress(25);
// 使用 Worker 池进行计算
const startTime = performance.now();
const result = await workerPool.execute({ c: cInput });
const endTime = performance.now();
updateProgress(75);
const flag = result.flag;
const computationTime = (endTime - startTime).toFixed(2);
// 验证 flag 格式
if (!flag.startsWith('flag{') || !flag.endsWith('}')) {
showToast('警告:Flag 格式可能不正确', 'error');
}
// 显示结果
const resultContent = document.getElementById('result-content');
resultContent.innerHTML = `
<div class="flag-result">${flag}</div>
<div style="margin-top: 15px; color: #666;">
<p><strong>验证信息:</strong></p>
<p>• 原始消息长度: ${flag.length} 字节</p>
<p>• 字符集匹配: ${validateCharset(flag.substring(6, flag.length - 1), tableInput) ? '✓' : '✗'}</p>
<p>• 预期长度: ${lengthInput} 字符</p>
<p>• 实际长度: ${flag.length - 7} 字符</p>
</div>
`;
// 更新统计
document.getElementById('bits').textContent = cInput.length;
document.getElementById('time').textContent = computationTime + 'ms';
document.getElementById('threads').textContent = workerPool.workers.length;
document.getElementById('status').textContent = '完成';
updateProgress(100);
showToast('计算完成!', 'success');
// 复制到剪贴板
navigator.clipboard.writeText(flag).then(() => {
console.log('Flag 已复制到剪贴板');
});
} catch (error) {
console.error(error);
showToast('计算出错:' + error.message, 'error');
document.getElementById('status').textContent = '错误';
}
}
// 验证字符集
function validateCharset(content, charset) {
if (!charset) return true;
for (let char of content) {
if (!charset.includes(char)) return false;
}
return true;
}
// 加载示例
function loadExample() {
document.getElementById('p-input').value = '407803049564139560409879631113358278888733140263084768485722310176731727783189074396823474461249041';
document.getElementById('c-input').value = '273724405776192840968808904199790097747266675483664217133748454869235934407461809379517600593224622';
document.getElementById('table-input').value = 'Lf';
document.getElementById('length-input').value = '100';
showToast('示例已加载', 'success');
}
// 清空所有输入
function clearAll() {
document.getElementById('p-input').value = '';
document.getElementById('c-input').value = '';
document.getElementById('table-input').value = '';
document.getElementById('length-input').value = '100';
document.getElementById('result-content').innerHTML = '<p style="color: #666;">等待计算...</p>';
document.getElementById('bits').textContent = '0';
document.getElementById('time').textContent = '0ms';
document.getElementById('threads').textContent = '1';
document.getElementById('status').textContent = '就绪';
updateProgress(0);
showToast('已清空所有内容', 'success');
}
// 页面加载时自动加载示例
window.addEventListener('load', () => {
setTimeout(loadExample, 500);
});
// 添加键盘快捷键
document.addEventListener('keydown', (e) => {
if (e.ctrlKey || e.metaKey) {
switch(e.key) {
case 'Enter':
e.preventDefault();
calculateFlag();
break;
case 'l':
e.preventDefault();
clearAll();
break;
case 'e':
e.preventDefault();
loadExample();
break;
}
}
});
</script>
</body>
</html>