Проверка исхода Crash-игры: алгоритм, безопасность
1) Цель проверки: что именно вы подтверждаете
Неподменяемость: оператор не мог изменить результат после вашей ставки (за счёт коммита хеша серверного сида).
Воспроизводимость: имея входные данные, вы получаете тот же множитель, что показала игра.
Целостность процедуры: формат сообщения, инкремент `nonce`, правило округления и «house edge» применены строго по спецификации.
2) Данные, без которых проверка невозможна
1. Server Seed Hash (коммит) — публикуется до использования соответствующего `Server Seed`.
2. Server Seed (раскрывается позже/по окончании периода).
3. Client Seed (ваш сид; вы задаёте его сами или платформа генерирует).
4. Nonce (счётчик ваших ставок в рамках текущего `Server Seed`).
5. Алгоритм хеширования (обычно `HMAC-SHA256` или `SHA-256`).
6. Формат сообщения (пример: `"
7. Формула маппинга хеша → множитель (и правило округления/минимума).
3) Алгоритм проверки (7 шагов)
1. Сверьте коммит: посчитайте `SHA-256(ServerSeed)` и сравните с опубликованным `ServerSeedHash`.
2. Соберите сообщение: строго в формате платформы (например, `msg = ClientSeed + ":" + Nonce`).
3. Посчитайте раундовый хеш:- при `HMAC-SHA256`: `RoundHash = HMAC_SHA256(key=ServerSeed, msg=message)`;
- при `SHA-256`: `RoundHash = SHA256(ServerSeed || message)` или как указано в спецификации.
- 4. Извлеките случайность: возьмите первые `k` бит (часто 52) → целое `r`, затем `u = r / 2^k`.
- 5. Примените формулу маппинга: преобразуйте `u` в множитель (house edge/особые кейсы учитываются по документации игры).
- 6. Округлите по правилам игры (например, до 2 знаков, минимум 1.00× и т. п.).
- 7. Сравните с итогом раунда в истории. Совпадение = корректная честность.
4) Псевдокод (можно адаптировать под Python/JS)
python
Вставьте сюда точную формулу маппинга от вашей платформы вместо stub_mapping()
import hmac, hashlib, math
def round_hash(server_seed: bytes, client_seed: str, nonce: int) -> bytes:
message = f"{client_seed}:{nonce}".encode("utf-8") формат смотрите в спецификации
return hmac.new(server_seed, message, hashlib.sha256).digest() либо hashlib.sha256(...)
def take_u_from_hash(h: bytes, k_bits=52) -> float:
Берём k старших бит как целое r
r = int.from_bytes(h, "big") >> (256 - k_bits)
return r / (1 << k_bits) u в [0, 1)
def stub_mapping(u: float) -> float:
ЗАГЛУШКА! Замените на формулу из документации вашей игры
Например, иногда используют преобразование вида: crash = floor( (const / (r+1)) 100 ) / 100
и/или «house edge» как редкое принудительное 1.00×. Не используйте этот стуб в реальной проверке.
return max(1.00, round(1.0 / max(1e-12, 1.0 - u), 2))
def verify(server_seed_hex, server_seed_hash_hex, client_seed, nonce, shown_multiplier):
server_seed = bytes.fromhex(server_seed_hex)
1) Коммит
assert hashlib.sha256(server_seed).hexdigest() == server_seed_hash_hex.lower()
2–3) Хеш раунда
h = round_hash(server_seed, client_seed, nonce)
4) u
u = take_u_from_hash(h)
5–6) маппинг + округление
calc_mult = stub_mapping(u)
7) сравнение
return abs(calc_mult - shown_multiplier) < 1e-9
Важно: вместо `stub_mapping` примените точную формулу из раздела Fairness вашей платформы; иначе проверка будет некорректной.
5) Частные случаи и подводные камни
Две ставки в одном раунде: у многих платформ `nonce` увеличивается на каждую вашу ставку, даже если они сделаны в один и тот же раунд (пример: ставка A → `nonce=42`, ставка B → `nonce=43`). Проверяйте по истории.
Смена `Client Seed`: при смене сида `nonce` обычно сбрасывается (или начинается новый поток). Сверьте правила именно вашей платформы.
Батчи `Server Seed`: один `Server Seed` действует на серию раундов, затем публикуется новый коммит; не путайте семена разных периодов.
Округление/минимум: несоответствие по второму знаку — в 90% случаев ошибка в правилах округления/минимума (например, фиксированный 1.00× при спец-условии).
Кодировка/пробелы: лишний пробел/перевод строки, неверный регистр, не-UTF-8 ломают проверку.
6) Чек-лист быстрой проверки раунда
1. Совпадает ли `SHA-256(ServerSeed)` с опубликованным `ServerSeedHash`?
2. Верно ли сформирован `message` и формат `nonce`?
3. Алгоритм (`HMAC-SHA256`/`SHA-256`) и ключ/порядок полей применены строго по спецификации?
4. Маппинг и округление идентичны документации?
5. Учитываются ли особые случаи (редкий «моментальный краш», минимум 1.00×, капы)?
6. Результат совпадает с историей игры до копейки?
7) Автоматизация контроля (практика)
Логи: сохраняйте у себя `client_seed`, последовательность `nonce`, метку времени, итоговый множитель.
Сэмплинг: после «ревила» `Server Seed` прогоняйте скриптом случайные 20–50 раундов; фиксируйте процент совпадений (должен быть 100%).
Регрессия: при смене версии игры/провайдера прогоните тот же набор.
Экспорт: храните CSV/JSON с исходниками — это ваш «аудит-трек».
8) Безопасность: как не ошибиться и не дать себя обмануть
Проверяйте локально/офлайн: не полагайтесь только на веб-валидатор оператора; держите собственный скрипт.
Не доверяйте раундам без полного пакета данных: нет формулы/формата — нет верификации.
Сильный `Client Seed`: задавайте случайный, меняйте периодически (это не повышает RTP, но исключает вопросы к воспроизводимости).
TLS/сессии: вход только по HTTPS, 2FA, отслеживание входов и выгрузок истории.
Никому не передавайте `Server Seed`: он публикуется оператором после периода; ваша задача — сверить, не «добыть» его заранее.
9) Типовые «ошибки новичков»
Перепутан порядок полей (`Nonce:ClientSeed` вместо `ClientSeed:Nonce`).
Счёт `nonce` с нуля вместо единицы (или наоборот).
Использован хеш всего раунда платформы (global nonce), а нужен ваш персональный `nonce`.
Игнор округления по правилам (banker’s rounding vs floor/ceil).
Сверка с активным, а не с уже раскрытым `Server Seed`.
10) «Красные флаги» у оператора
Нет публичного Server Seed Hash до старта периода.
Нельзя задать свой Client Seed или посмотреть nonce.
Отсутствует публичная формула маппинга хеша в множитель.
История раундов не даёт минимум данных для сверки.
Формат и алгоритм менялись без уведомления/архива спецификаций.
11) Австралийский контекст (AU)
Валюта: ведите учёт выигрышей/ставок в AUD, храните выгрузки историй (поддержка, спорные вопросы).
Ответственная игра (RG): лимиты депозита/времени, паузы и самоисключение — доступны в добросовестных приложениях; используйте их.
Платформенные практики: у добросовестных операторов блок «Fairness/Provably Fair» содержит полное описание и примеры верификации; отсутствие подробностей — повод выбирать другой сервис.
12) Итог
Проверка исхода Crash-игры — это чёткая процедура:- сверка коммита `Server Seed Hash`,
- восстановление `RoundHash` по `Server Seed`, `Client Seed`, `nonce` и алгоритму,
- применение опубликованной формулы маппинга и правил округления,
- идентичный множитель в вашей проверке и в истории игры.
Держите собственный скрипт, логируйте входные данные и периодически проверяйте случайные раунды. Так вы подтверждаете честность не на словах, а математически.