Check any round yourself
Every round on Haddzy is worked out from numbers you can see: our seed, your seed and a counter. Put them in below and this page replays the round right here in your browser — nothing you type is sent to us — and if it lands where your game landed, nothing was touched.
New to this? Read the plain-English walkthrough.
Run it yourself
This is the exact source running on our servers. Copy it, paste it anywhere, and confirm we are not lying about your results.
JavaScript (Node.js)
import { createHmac } from 'node:crypto';
export function* hmacFloatStream(serverSeed, clientSeed, nonce, gameName) {
let cursor = 0n;
while (true) {
const input = `${clientSeed}:${nonce}:${gameName}:${cursor}`;
const hmac = createHmac('sha256', serverSeed).update(input).digest();
for (let i = 0; i < 8; i++) {
yield hmac.readUInt32BE(i * 4) / 0x1_0000_0000;
}
cursor++;
}
}Python 3
import hmac, hashlib
def hmac_float_stream(server_seed: str, client_seed: str, nonce: int, game_name: str):
cursor = 0
while True:
msg = f"{client_seed}:{nonce}:{game_name}:{cursor}".encode()
digest = hmac.new(server_seed.encode(), msg, hashlib.sha256).digest()
for i in range(8):
chunk = digest[i*4:(i+1)*4]
yield int.from_bytes(chunk, 'big') / (1 << 32)
cursor += 1Originals engine
Diamonds, Video Poker, Wheel draw from a byte stream instead of a 32-bit float stream, and the game name is not part of the message. Each HMAC round yields 32 bytes; every four bytes make one float. The cursor is the byte offset into that stream, so a bet can be replayed from exactly where it started.
JavaScript (Node.js)
import { createHmac } from 'node:crypto';
export function* pfByteStream(serverSeed, clientSeed, nonce, cursor = 0) {
let round = Math.floor(cursor / 32);
let offset = cursor % 32;
while (true) {
const input = `${clientSeed}:${nonce}:${round}`;
const block = createHmac('sha256', serverSeed).update(input).digest();
while (offset < 32) yield block[offset++];
offset = 0;
round++;
}
}
export function pfFloats(serverSeed, clientSeed, nonce, cursor, count) {
const bytes = pfByteStream(serverSeed, clientSeed, nonce, cursor);
const floats = [];
for (let i = 0; i < count; i++) {
let value = 0;
for (let j = 0; j < 4; j++) value += bytes.next().value / 256 ** (j + 1);
floats.push(value);
}
return floats;
}Python 3
import hmac, hashlib
def pf_byte_stream(server_seed: str, client_seed: str, nonce: int, cursor: int = 0):
round_index, offset = divmod(cursor, 32)
while True:
msg = f"{client_seed}:{nonce}:{round_index}".encode()
block = hmac.new(server_seed.encode(), msg, hashlib.sha256).digest()
while offset < 32:
yield block[offset]
offset += 1
offset = 0
round_index += 1
def pf_floats(server_seed: str, client_seed: str, nonce: int, cursor: int, count: int):
stream = pf_byte_stream(server_seed, client_seed, nonce, cursor)
return [
sum(next(stream) / 256 ** (j + 1) for j in range(4))
for _ in range(count)
]