Generate a random number using a server-side seed and client input.
HTML
<h2>TRANSPARENCY SYSTEM</h2>
<label>Server Seed:</label>
<input type="text" id="serverSeed" placeholder="server seed (hex or string)" />
<label>Server Nonce:</label>
<input type="number" id="serverNonce" placeholder="e.g. 2" />
<label>Client Seed:</label>
<input type="text" id="clientSeed" placeholder="client seed (user input)" />
<button onclick="verify()">Oblicz</button>
<h3>Result: <span id="roll_result">–</span></h3>
CSS
* {
font-family: sans-serif;
color: #fff;
box-sizing: border-box;
}
body {
display: flex;
flex-direction: column;
background: #1B1F2B;
}
label {
font-family: sans-serif;
color: #BFBFBF;
margin-bottom: 6px;
font-size: 14px;
}
button {
height: 44px;
width: 250px;
background: rgba(49, 187, 255, 0.1);
border: 1px solid #31bbff;
border-radius: 8px;
font-size: 14px;
}
input {
width: 500px;
border: 1px solid #2E394F;
height: 44px;
padding: 0 16px;
font-size: 16px;
background-color: #161921;
margin-bottom: 16px;
border-radius: 8px;
}
input::placeholder {
color: #8892A5;
}
JavaScript
async function getRoll(serverSeed, serverNonce, clientSeed) {
const enc = new TextEncoder();
const key = enc.encode(serverSeed);
const message = enc.encode(clientSeed + '-' + serverNonce.toString());
const cryptoKey = await crypto.subtle.importKey(
'raw',
key,
{ name: 'HMAC', hash: 'SHA-512' },
false,
['sign']
);
const signature = await crypto.subtle.sign('HMAC', cryptoKey, message);
const hashArray = Array.from(new Uint8Array(signature));
const hex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
const rollHex = hex.substring(0, 7);
const number = parseInt(rollHex.replace(/[^a-f0-9]/gi, ''), 16);
return (number % 100000) + 1;
}
async function verify() {
const serverSeed = document.getElementById('serverSeed').value.trim();
const serverNonce = parseInt(document.getElementById('serverNonce').value.trim(), 10);
const clientSeed = document.getElementById('clientSeed').value.trim() || '';
const resultEl = document.getElementById('roll_result');
if (!serverSeed || isNaN(serverNonce)) {
resultEl.textContent = '⚠️ Wprowadź wszystkie dane.';
return;
}
try {
const roll = await getRoll(serverSeed, serverNonce, clientSeed);
resultEl.textContent = roll;
} catch (err) {
resultEl.textContent = '❌ Błąd podczas liczenia.';
}
}