SuperMiner commited on
Commit
c19a4da
·
verified ·
1 Parent(s): 5fa6ba0

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +808 -19
index.html CHANGED
@@ -1,19 +1,808 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>CTF Flag Calculator - Multi-Threaded Solver</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ :root {
15
+ --primary: #6366f1;
16
+ --primary-dark: #4f46e5;
17
+ --secondary: #22d3ee;
18
+ --success: #10b981;
19
+ --warning: #f59e0b;
20
+ --danger: #ef4444;
21
+ --dark: #1e293b;
22
+ --light: #f1f5f9;
23
+ --card-bg: #ffffff;
24
+ --text: #334155;
25
+ --border: #e2e8f0;
26
+ --shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1);
27
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
28
+ }
29
+
30
+ body {
31
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
32
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
33
+ min-height: 100vh;
34
+ color: var(--text);
35
+ position: relative;
36
+ overflow-x: hidden;
37
+ }
38
+
39
+ body::before {
40
+ content: '';
41
+ position: fixed;
42
+ top: 0;
43
+ left: 0;
44
+ right: 0;
45
+ bottom: 0;
46
+ background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="%23ffffff" fill-opacity="0.05" d="M0,96L48,112C96,128,192,160,288,160C384,160,480,128,576,122.7C672,117,768,139,864,144C960,149,1056,139,1152,122.7C1248,107,1344,85,1392,74.7L1440,64L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"></path></svg>') no-repeat bottom;
47
+ background-size: cover;
48
+ opacity: 0.3;
49
+ pointer-events: none;
50
+ }
51
+
52
+ .container {
53
+ max-width: 1400px;
54
+ margin: 0 auto;
55
+ padding: 2rem;
56
+ position: relative;
57
+ z-index: 1;
58
+ }
59
+
60
+ header {
61
+ text-align: center;
62
+ margin-bottom: 3rem;
63
+ animation: fadeInDown 0.8s ease;
64
+ }
65
+
66
+ h1 {
67
+ font-size: 2.5rem;
68
+ font-weight: 800;
69
+ color: white;
70
+ margin-bottom: 0.5rem;
71
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.2);
72
+ }
73
+
74
+ .subtitle {
75
+ color: rgba(255,255,255,0.9);
76
+ font-size: 1.1rem;
77
+ }
78
+
79
+ .credit {
80
+ margin-top: 1rem;
81
+ font-size: 0.9rem;
82
+ color: rgba(255,255,255,0.7);
83
+ }
84
+
85
+ .credit a {
86
+ color: var(--secondary);
87
+ text-decoration: none;
88
+ transition: color 0.3s;
89
+ }
90
+
91
+ .credit a:hover {
92
+ color: white;
93
+ text-decoration: underline;
94
+ }
95
+
96
+ .main-grid {
97
+ display: grid;
98
+ grid-template-columns: 1fr 1fr;
99
+ gap: 2rem;
100
+ margin-bottom: 2rem;
101
+ }
102
+
103
+ @media (max-width: 968px) {
104
+ .main-grid {
105
+ grid-template-columns: 1fr;
106
+ }
107
+ }
108
+
109
+ .card {
110
+ background: var(--card-bg);
111
+ border-radius: 16px;
112
+ padding: 2rem;
113
+ box-shadow: var(--shadow-lg);
114
+ backdrop-filter: blur(10px);
115
+ background: rgba(255,255,255,0.95);
116
+ animation: fadeInUp 0.8s ease;
117
+ }
118
+
119
+ .card-title {
120
+ font-size: 1.5rem;
121
+ font-weight: 700;
122
+ color: var(--dark);
123
+ margin-bottom: 1.5rem;
124
+ display: flex;
125
+ align-items: center;
126
+ gap: 0.5rem;
127
+ }
128
+
129
+ .icon {
130
+ width: 28px;
131
+ height: 28px;
132
+ display: inline-block;
133
+ }
134
+
135
+ .input-group {
136
+ margin-bottom: 1.5rem;
137
+ }
138
+
139
+ label {
140
+ display: block;
141
+ font-weight: 600;
142
+ margin-bottom: 0.5rem;
143
+ color: var(--dark);
144
+ }
145
+
146
+ input, textarea {
147
+ width: 100%;
148
+ padding: 0.75rem 1rem;
149
+ border: 2px solid var(--border);
150
+ border-radius: 8px;
151
+ font-size: 1rem;
152
+ transition: all 0.3s;
153
+ font-family: 'Courier New', monospace;
154
+ }
155
+
156
+ input:focus, textarea:focus {
157
+ outline: none;
158
+ border-color: var(--primary);
159
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
160
+ }
161
+
162
+ textarea {
163
+ resize: vertical;
164
+ min-height: 100px;
165
+ }
166
+
167
+ .btn {
168
+ padding: 0.75rem 2rem;
169
+ border: none;
170
+ border-radius: 8px;
171
+ font-size: 1rem;
172
+ font-weight: 600;
173
+ cursor: pointer;
174
+ transition: all 0.3s;
175
+ display: inline-flex;
176
+ align-items: center;
177
+ gap: 0.5rem;
178
+ }
179
+
180
+ .btn-primary {
181
+ background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
182
+ color: white;
183
+ }
184
+
185
+ .btn-primary:hover {
186
+ transform: translateY(-2px);
187
+ box-shadow: var(--shadow-lg);
188
+ }
189
+
190
+ .btn-primary:disabled {
191
+ opacity: 0.5;
192
+ cursor: not-allowed;
193
+ transform: none;
194
+ }
195
+
196
+ .btn-secondary {
197
+ background: var(--light);
198
+ color: var(--dark);
199
+ }
200
+
201
+ .btn-secondary:hover {
202
+ background: var(--border);
203
+ }
204
+
205
+ .btn-group {
206
+ display: flex;
207
+ gap: 1rem;
208
+ flex-wrap: wrap;
209
+ }
210
+
211
+ .progress-section {
212
+ margin-top: 2rem;
213
+ padding: 1.5rem;
214
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
215
+ border-radius: 12px;
216
+ display: none;
217
+ }
218
+
219
+ .progress-section.active {
220
+ display: block;
221
+ animation: slideDown 0.5s ease;
222
+ }
223
+
224
+ .progress-bar {
225
+ height: 30px;
226
+ background: white;
227
+ border-radius: 15px;
228
+ overflow: hidden;
229
+ margin-bottom: 1rem;
230
+ box-shadow: inset 0 2px 4px rgba(0,0,0,0.1);
231
+ }
232
+
233
+ .progress-fill {
234
+ height: 100%;
235
+ background: linear-gradient(90deg, var(--primary) 0%, var(--secondary) 100%);
236
+ width: 0%;
237
+ transition: width 0.3s ease;
238
+ display: flex;
239
+ align-items: center;
240
+ justify-content: center;
241
+ color: white;
242
+ font-weight: 600;
243
+ font-size: 0.9rem;
244
+ }
245
+
246
+ .stats-grid {
247
+ display: grid;
248
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
249
+ gap: 1rem;
250
+ margin-top: 1rem;
251
+ }
252
+
253
+ .stat-item {
254
+ background: white;
255
+ padding: 1rem;
256
+ border-radius: 8px;
257
+ text-align: center;
258
+ }
259
+
260
+ .stat-value {
261
+ font-size: 1.5rem;
262
+ font-weight: 700;
263
+ color: var(--primary);
264
+ }
265
+
266
+ .stat-label {
267
+ font-size: 0.9rem;
268
+ color: var(--text);
269
+ margin-top: 0.25rem;
270
+ }
271
+
272
+ .result-section {
273
+ margin-top: 2rem;
274
+ padding: 2rem;
275
+ background: linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%);
276
+ border-radius: 12px;
277
+ display: none;
278
+ }
279
+
280
+ .result-section.active {
281
+ display: block;
282
+ animation: slideDown 0.5s ease;
283
+ }
284
+
285
+ .flag-display {
286
+ background: white;
287
+ padding: 1.5rem;
288
+ border-radius: 8px;
289
+ font-family: 'Courier New', monospace;
290
+ font-size: 1.1rem;
291
+ word-break: break-all;
292
+ margin-top: 1rem;
293
+ box-shadow: var(--shadow);
294
+ }
295
+
296
+ .worker-status {
297
+ display: grid;
298
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
299
+ gap: 1rem;
300
+ margin-top: 1rem;
301
+ }
302
+
303
+ .worker-card {
304
+ background: white;
305
+ padding: 1rem;
306
+ border-radius: 8px;
307
+ border-left: 4px solid var(--primary);
308
+ }
309
+
310
+ .worker-name {
311
+ font-weight: 600;
312
+ color: var(--dark);
313
+ margin-bottom: 0.5rem;
314
+ }
315
+
316
+ .worker-progress {
317
+ font-size: 0.9rem;
318
+ color: var(--text);
319
+ }
320
+
321
+ .log-section {
322
+ margin-top: 2rem;
323
+ max-height: 300px;
324
+ overflow-y: auto;
325
+ background: #f8fafc;
326
+ border-radius: 8px;
327
+ padding: 1rem;
328
+ }
329
+
330
+ .log-entry {
331
+ padding: 0.5rem;
332
+ margin-bottom: 0.5rem;
333
+ border-radius: 4px;
334
+ font-family: 'Courier New', monospace;
335
+ font-size: 0.9rem;
336
+ animation: fadeIn 0.3s ease;
337
+ }
338
+
339
+ .log-info {
340
+ background: #dbeafe;
341
+ color: #1e40af;
342
+ }
343
+
344
+ .log-success {
345
+ background: #d1fae5;
346
+ color: #065f46;
347
+ }
348
+
349
+ .log-error {
350
+ background: #fee2e2;
351
+ color: #991b1b;
352
+ }
353
+
354
+ @keyframes fadeInDown {
355
+ from {
356
+ opacity: 0;
357
+ transform: translateY(-20px);
358
+ }
359
+ to {
360
+ opacity: 1;
361
+ transform: translateY(0);
362
+ }
363
+ }
364
+
365
+ @keyframes fadeInUp {
366
+ from {
367
+ opacity: 0;
368
+ transform: translateY(20px);
369
+ }
370
+ to {
371
+ opacity: 1;
372
+ transform: translateY(0);
373
+ }
374
+ }
375
+
376
+ @keyframes slideDown {
377
+ from {
378
+ opacity: 0;
379
+ max-height: 0;
380
+ }
381
+ to {
382
+ opacity: 1;
383
+ max-height: 1000px;
384
+ }
385
+ }
386
+
387
+ @keyframes fadeIn {
388
+ from { opacity: 0; }
389
+ to { opacity: 1; }
390
+ }
391
+
392
+ .spinner {
393
+ display: inline-block;
394
+ width: 20px;
395
+ height: 20px;
396
+ border: 3px solid rgba(255,255,255,0.3);
397
+ border-radius: 50%;
398
+ border-top-color: white;
399
+ animation: spin 1s ease-in-out infinite;
400
+ }
401
+
402
+ @keyframes spin {
403
+ to { transform: rotate(360deg); }
404
+ }
405
+
406
+ .algorithm-info {
407
+ background: #f0f9ff;
408
+ border: 1px solid #bae6fd;
409
+ border-radius: 8px;
410
+ padding: 1rem;
411
+ margin-bottom: 1rem;
412
+ }
413
+
414
+ .algorithm-info h3 {
415
+ color: #0369a1;
416
+ margin-bottom: 0.5rem;
417
+ font-size: 1rem;
418
+ }
419
+
420
+ .algorithm-info p {
421
+ color: #0c4a6e;
422
+ font-size: 0.9rem;
423
+ line-height: 1.5;
424
+ }
425
+ </style>
426
+ </head>
427
+ <body>
428
+ <div class="container">
429
+ <header>
430
+ <h1>🚩 CTF Flag Calculator</h1>
431
+ <p class="subtitle">多线程并行计算破解模运算Flag</p>
432
+ <p class="credit">Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a></p>
433
+ </header>
434
+
435
+ <div class="main-grid">
436
+ <div class="card">
437
+ <h2 class="card-title">
438
+ <span class="icon">📝</span>
439
+ 输入参数
440
+ </h2>
441
+
442
+ <div class="input-group">
443
+ <label for="prime-p">质数 p (328位)</label>
444
+ <textarea id="prime-p" rows="3">407803049564139560409879631113358278888733140263084768485722310176731727783189074396823474461249041</textarea>
445
+ </div>
446
+
447
+ <div class="input-group">
448
+ <label for="cipher-c">密文 c = m % p</label>
449
+ <textarea id="cipher-c" rows="3">273724405776192840968808904199790097747266675483664217133748454869235934407461809379517600593224622</textarea>
450
+ </div>
451
+
452
+ <div class="input-group">
453
+ <label for="charset">字符集</label>
454
+ <input type="text" id="charset" value="Lf" readonly>
455
+ </div>
456
+
457
+ <div class="input-group">
458
+ <label for="flag-length">Flag长度(不含flag{})</label>
459
+ <input type="number" id="flag-length" value="100" readonly>
460
+ </div>
461
+
462
+ <div class="btn-group">
463
+ <button class="btn btn-primary" onclick="startCalculation()">
464
+ <span>开始破解</span>
465
+ </button>
466
+ <button class="btn btn-secondary" onclick="resetAll()">
467
+ 重置
468
+ </button>
469
+ </div>
470
+ </div>
471
+
472
+ <div class="card">
473
+ <h2 class="card-title">
474
+ <span class="icon">⚡</span>
475
+ 算法优化说明
476
+ </h2>
477
+
478
+ <div class="algorithm-info">
479
+ <h3>🔧 多线程并行计算</h3>
480
+ <p>使用Web Workers将计算任务分配到多个线程,充分利用多核CPU性能,显著提升计算速度。</p>
481
+ </div>
482
+
483
+ <div class="algorithm-info">
484
+ <h3>🎯 智能空间分割</h3>
485
+ <p>将2^100的搜索空间智能分割成多个子任务,每个Worker负责一个子空间,避免重复计算。</p>
486
+ </div>
487
+
488
+ <div class="algorithm-info">
489
+ <h3>📊 实时进度监控</h3>
490
+ <p>实时显示每个Worker的计算进度和状态,提供详细的性能统计信息。</p>
491
+ </div>
492
+
493
+ <div class="algorithm-info">
494
+ <h3>🚀 早期终止优化</h3>
495
+ <p>一旦找到正确的Flag,立即停止所有Worker的计算,避免资源浪费。</p>
496
+ </div>
497
+
498
+ <div class="worker-status" id="worker-status">
499
+ <!-- Worker状态将动态生成 -->
500
+ </div>
501
+ </div>
502
+ </div>
503
+
504
+ <div class="progress-section" id="progress-section">
505
+ <h3 style="margin-bottom: 1rem; color: var(--dark);">计算进度</h3>
506
+ <div class="progress-bar">
507
+ <div class="progress-fill" id="progress-fill">0%</div>
508
+ </div>
509
+ <div class="stats-grid">
510
+ <div class="stat-item">
511
+ <div class="stat-value" id="workers-active">0</div>
512
+ <div class="stat-label">活跃Worker</div>
513
+ </div>
514
+ <div class="stat-item">
515
+ <div class="stat-value" id="combinations-checked">0</div>
516
+ <div class="stat-label">已检查组合</div>
517
+ </div>
518
+ <div class="stat-item">
519
+ <div class="stat-value" id="elapsed-time">0s</div>
520
+ <div class="stat-label">已用时间</div>
521
+ </div>
522
+ <div class="stat-item">
523
+ <div class="stat-value" id="speed">0/s</div>
524
+ <div class="stat-label">计算速度</div>
525
+ </div>
526
+ </div>
527
+ </div>
528
+
529
+ <div class="result-section" id="result-section">
530
+ <h3 style="color: var(--success); margin-bottom: 1rem;">🎉 找到Flag!</h3>
531
+ <div class="flag-display" id="flag-result"></div>
532
+ <button class="btn btn-primary" onclick="copyFlag()" style="margin-top: 1rem;">
533
+ 复制Flag
534
+ </button>
535
+ </div>
536
+
537
+ <div class="log-section" id="log-section">
538
+ <!-- 日志将动态生成 -->
539
+ </div>
540
+ </div>
541
+
542
+ <script>
543
+ // Worker代码(作为字符串)
544
+ const workerCode = `
545
+ self.onmessage = function(e) {
546
+ const { start, end, p, c, charset, flagLength, workerId, step } = e.data;
547
+
548
+ const prefix = "flag{";
549
+ const suffix = "}";
550
+
551
+ function generateCombination(index, current) {
552
+ if (index === flagLength) {
553
+ const flagStr = prefix + current + suffix;
554
+ const flagBytes = new TextEncoder().encode(flagStr);
555
+ const m = bytesToLong(flagBytes);
556
+
557
+ if (m % p === c) {
558
+ self.postMessage({
559
+ type: 'found',
560
+ flag: flagStr,
561
+ workerId: workerId
562
+ });
563
+ return true;
564
+ }
565
+ return false;
566
+ }
567
+
568
+ for (let i = 0; i < charset.length; i++) {
569
+ if (generateCombination(index + 1, current + charset[i])) {
570
+ return true;
571
+ }
572
+ }
573
+ return false;
574
+ }
575
+
576
+ function bytesToLong(bytes) {
577
+ let result = 0n;
578
+ for (let i = 0; i < bytes.length; i++) {
579
+ result = (result << 8n) | BigInt(bytes[i]);
580
+ }
581
+ return result;
582
+ }
583
+
584
+ // 使用优化的迭代方法避免递归栈溢出
585
+ let found = false;
586
+ let total = 0n;
587
+
588
+ for (let i = start; i <= end && !found; i += step) {
589
+ // 将数字转换为二进制字符串,然后映射到字符集
590
+ let binaryStr = i.toString(2).padStart(flagLength, '0');
591
+ if (binaryStr.length > flagLength) continue;
592
+
593
+ let flagContent = '';
594
+ for (let j = 0; j < flagLength; j++) {
595
+ flagContent += charset[parseInt(binaryStr[j])];
596
+ }
597
+
598
+ const flagStr = prefix + flagContent + suffix;
599
+ const flagBytes = new TextEncoder().encode(flagStr);
600
+ const m = bytesToLong(flagBytes);
601
+
602
+ if (m % p === c) {
603
+ self.postMessage({
604
+ type: 'found',
605
+ flag: flagStr,
606
+ workerId: workerId
607
+ });
608
+ found = true;
609
+ break;
610
+ }
611
+
612
+ total++;
613
+
614
+ // 定期报告进度
615
+ if (total % 10000n === 0n) {
616
+ self.postMessage({
617
+ type: 'progress',
618
+ workerId: workerId,
619
+ checked: Number(total),
620
+ current: i
621
+ });
622
+ }
623
+ }
624
+
625
+ if (!found) {
626
+ self.postMessage({
627
+ type: 'complete',
628
+ workerId: workerId,
629
+ totalChecked: Number(total)
630
+ });
631
+ }
632
+ };
633
+ `;
634
+
635
+ let workers = [];
636
+ let startTime = null;
637
+ let totalChecked = 0;
638
+ let activeWorkers = 0;
639
+ let calculationComplete = false;
640
+
641
+ function addLog(message, type = 'info') {
642
+ const logSection = document.getElementById('log-section');
643
+ const logEntry = document.createElement('div');
644
+ logEntry.className = `log-entry log-${type}`;
645
+ logEntry.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
646
+ logSection.appendChild(logEntry);
647
+ logSection.scrollTop = logSection.scrollHeight;
648
+ }
649
+
650
+ function startCalculation() {
651
+ resetAll();
652
+
653
+ const p = BigInt(document.getElementById('prime-p').value);
654
+ const c = BigInt(document.getElementById('cipher-c').value);
655
+ const charset = document.getElementById('charset').value;
656
+ const flagLength = parseInt(document.getElementById('flag-length').value);
657
+
658
+ // 创建Blob URL
659
+ const blob = new Blob([workerCode], { type: 'application/javascript' });
660
+ const workerUrl = URL.createObjectURL(blob);
661
+
662
+ // 确定Worker数量(根据CPU核心数)
663
+ const numWorkers = navigator.hardwareConcurrency || 4;
664
+
665
+ // 计算每个Worker的搜索范围
666
+ const totalCombinations = BigInt(2) ** BigInt(flagLength);
667
+ const chunkSize = totalCombinations / BigInt(numWorkers);
668
+
669
+ document.getElementById('progress-section').classList.add('active');
670
+ document.getElementById('worker-status').innerHTML = '';
671
+
672
+ startTime = Date.now();
673
+ activeWorkers = numWorkers;
674
+
675
+ addLog(`开始破解进程,使用${numWorkers}个Worker线程`, 'info');
676
+ addLog(`总搜索空间: 2^${flagLength} = ${totalCombinations.toString()}`, 'info');
677
+
678
+ // 创建Worker
679
+ for (let i = 0; i < numWorkers; i++) {
680
+ const start = Number(chunkSize * BigInt(i));
681
+ const end = Number(chunkSize * BigInt(i + 1) - 1n);
682
+
683
+ const worker = new Worker(workerUrl);
684
+ workers.push(worker);
685
+
686
+ // 创建Worker状态卡片
687
+ const workerCard = document.createElement('div');
688
+ workerCard.className = 'worker-card';
689
+ workerCard.id = `worker-${i}`;
690
+ workerCard.innerHTML = `
691
+ <div class="worker-name">Worker ${i + 1}</div>
692
+ <div class="worker-progress">初始化中...</div>
693
+ `;
694
+ document.getElementById('worker-status').appendChild(workerCard);
695
+
696
+ worker.onmessage = function(e) {
697
+ const { type, flag, workerId, checked, current, totalChecked } = e.data;
698
+
699
+ if (type === 'found') {
700
+ calculationComplete = true;
701
+ displayResult(flag);
702
+ stopAllWorkers();
703
+ addLog(`Worker ${workerId + 1} 找到Flag: ${flag}`, 'success');
704
+ } else if (type === 'progress') {
705
+ updateWorkerStatus(workerId, checked);
706
+ totalChecked += checked;
707
+ updateProgress();
708
+ } else if (type === 'complete') {
709
+ activeWorkers--;
710
+ updateWorkerStatus(workerId, totalChecked, true);
711
+ if (activeWorkers === 0 && !calculationComplete) {
712
+ addLog('所有Worker完成计算,未找到Flag', 'error');
713
+ }
714
+ }
715
+ };
716
+
717
+ // 启动Worker
718
+ worker.postMessage({
719
+ start,
720
+ end,
721
+ p: p.toString(),
722
+ c: c.toString(),
723
+ charset,
724
+ flagLength,
725
+ workerId: i,
726
+ step: 1
727
+ });
728
+ }
729
+ }
730
+
731
+ function updateWorkerStatus(workerId, checked, complete = false) {
732
+ const workerCard = document.getElementById(`worker-${workerId}`);
733
+ if (workerCard) {
734
+ const progressDiv = workerCard.querySelector('.worker-progress');
735
+ if (complete) {
736
+ progressDiv.textContent = `完成 - 检查了 ${checked} 个组合`;
737
+ } else {
738
+ progressDiv.textContent = `检查了 ${checked} 个组合`;
739
+ }
740
+ }
741
+ }
742
+
743
+ function updateProgress() {
744
+ if (!startTime) return;
745
+
746
+ const elapsed = (Date.now() - startTime) / 1000;
747
+ const speed = Math.round(totalChecked / elapsed);
748
+
749
+ document.getElementById('workers-active').textContent = activeWorkers;
750
+ document.getElementById('combinations-checked').textContent = totalChecked.toLocaleString();
751
+ document.getElementById('elapsed-time').textContent = elapsed.toFixed(1) + 's';
752
+ document.getElementById('speed').textContent = speed.toLocaleString() + '/s';
753
+
754
+ // 这里可以添加更精确的进度计算
755
+ const progress = Math.min((totalChecked / (2 ** 20)) * 100, 100); // 假设总检查2^20作为参考
756
+ const progressFill = document.getElementById('progress-fill');
757
+ progressFill.style.width = progress + '%';
758
+ progressFill.textContent = progress.toFixed(2) + '%';
759
+ }
760
+
761
+ function displayResult(flag) {
762
+ document.getElementById('flag-result').textContent = flag;
763
+ document.getElementById('result-section').classList.add('active');
764
+
765
+ // 滚动到结果
766
+ document.getElementById('result-section').scrollIntoView({
767
+ behavior: 'smooth',
768
+ block: 'center'
769
+ });
770
+ }
771
+
772
+ function copyFlag() {
773
+ const flag = document.getElementById('flag-result').textContent;
774
+ navigator.clipboard.writeText(flag).then(() => {
775
+ addLog('Flag已复制到剪贴板', 'success');
776
+ });
777
+ }
778
+
779
+ function stopAllWorkers() {
780
+ workers.forEach(worker => {
781
+ worker.terminate();
782
+ });
783
+ workers = [];
784
+ activeWorkers = 0;
785
+ }
786
+
787
+ function resetAll() {
788
+ stopAllWorkers();
789
+
790
+ document.getElementById('progress-section').classList.remove('active');
791
+ document.getElementById('result-section').classList.remove('active');
792
+ document.getElementById('log-section').innerHTML = '';
793
+ document.getElementById('worker-status').innerHTML = '';
794
+
795
+ totalChecked = 0;
796
+ activeWorkers = 0;
797
+ calculationComplete = false;
798
+ startTime = null;
799
+ }
800
+
801
+ // 页面加载时添加初始日志
802
+ window.addEventListener('load', () => {
803
+ addLog('系统初始化完成,准备开始破解', 'info');
804
+ addLog('提示:此算法使用多线程并行计算,充分利用CPU性能', 'info');
805
+ });
806
+ </script>
807
+ </body>
808
+ </html>