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.';
  }
}