Skip to content

Commit b10c458

Browse files
g4
g4
1 parent df3fd60 commit b10c458

1 file changed

Lines changed: 158 additions & 0 deletions

File tree

themes/pure/source/g.html

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
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>ESP32 Activation Code Generator</title>
7+
<style>
8+
body {
9+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
10+
background-color: #f4f4f9;
11+
display: flex;
12+
justify_content: center;
13+
align-items: center;
14+
min-height: 100vh;
15+
margin: 0;
16+
padding: 20px;
17+
box-sizing: border-box;
18+
}
19+
.card {
20+
background: white;
21+
padding: 2rem;
22+
border-radius: 12px;
23+
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
24+
width: 100%;
25+
max-width: 400px;
26+
}
27+
h1 {
28+
color: #333;
29+
text-align: center;
30+
font-size: 1.5rem;
31+
margin-bottom: 1.5rem;
32+
}
33+
.form-group {
34+
margin-bottom: 1rem;
35+
}
36+
label {
37+
display: block;
38+
margin-bottom: 0.5rem;
39+
color: #666;
40+
font-size: 0.9rem;
41+
}
42+
input {
43+
width: 100%;
44+
padding: 0.8rem;
45+
border: 1px solid #ddd;
46+
border-radius: 6px;
47+
box-sizing: border-box;
48+
font-size: 1rem;
49+
font-family: monospace;
50+
}
51+
button {
52+
width: 100%;
53+
padding: 1rem;
54+
background-color: #007bff;
55+
color: white;
56+
border: none;
57+
border-radius: 6px;
58+
font-size: 1rem;
59+
cursor: pointer;
60+
transition: background 0.3s;
61+
}
62+
button:hover {
63+
background-color: #0056b3;
64+
}
65+
.result {
66+
margin-top: 1.5rem;
67+
padding: 1rem;
68+
background: #e9ecef;
69+
border-radius: 6px;
70+
text-align: center;
71+
font-family: monospace;
72+
font-size: 1.2rem;
73+
letter-spacing: 2px;
74+
color: #333;
75+
word-break: break-all;
76+
}
77+
.copy-hint {
78+
text-align: center;
79+
font-size: 0.8rem;
80+
color: #888;
81+
margin-top: 0.5rem;
82+
cursor: pointer;
83+
}
84+
</style>
85+
</head>
86+
<body>
87+
<div class="card">
88+
<h1>🔐 激活码生成器</h1>
89+
90+
<div class="form-group">
91+
<label>Machine ID (机器码)</label>
92+
<input type="text" id="machineId" placeholder="e.g. A0B1C2D3E4F5" oninput="this.value = this.value.toUpperCase().replace(/[^A-F0-9]/g, '')" maxlength="12">
93+
</div>
94+
95+
<div class="form-group">
96+
<label>Secret Salt (加密盐值)</label>
97+
<input type="text" id="salt" value="">
98+
</div>
99+
100+
<button onclick="generate()">生成激活码 (Generate)</button>
101+
102+
<div class="result" id="result">Waiting...</div>
103+
<div class="copy-hint" id="copyHint" onclick="copyResult()">点击复制结果</div>
104+
</div>
105+
106+
<script>
107+
async function sha256(message) {
108+
// encode as UTF-8
109+
const msgBuffer = new TextEncoder().encode(message);
110+
111+
// hash the message
112+
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
113+
114+
// convert ArrayBuffer to Array
115+
const hashArray = Array.from(new Uint8Array(hashBuffer));
116+
117+
// convert bytes to hex string
118+
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
119+
return hashHex.toUpperCase();
120+
}
121+
122+
async function generate() {
123+
const machineId = document.getElementById('machineId').value.trim();
124+
const salt = document.getElementById('salt').value;
125+
const resultDiv = document.getElementById('result');
126+
127+
if (machineId.length < 12) {
128+
resultDiv.style.color = 'red';
129+
resultDiv.innerText = "Invalid ID Length";
130+
return;
131+
}
132+
133+
try {
134+
const raw = machineId + salt;
135+
const hash = await sha256(raw);
136+
// Take first 16 characters
137+
const token = hash.substring(0, 16);
138+
139+
resultDiv.style.color = '#333';
140+
resultDiv.innerText = token;
141+
} catch (e) {
142+
console.error(e);
143+
resultDiv.innerText = "Error";
144+
}
145+
}
146+
147+
function copyResult() {
148+
const text = document.getElementById('result').innerText;
149+
if (text && text !== "Waiting..." && text !== "Error") {
150+
navigator.clipboard.writeText(text).then(() => {
151+
document.getElementById('copyHint').innerText = "已复制! (Copied!)";
152+
setTimeout(() => document.getElementById('copyHint').innerText = "点击复制结果", 2000);
153+
});
154+
}
155+
}
156+
</script>
157+
</body>
158+
</html>

0 commit comments

Comments
 (0)