AWPBattle.com
[ PROVABLY FAIR ]

Проверка честности

Для каждого открытия публикуется public_hash до результата. После открытия раскрываются server_seed и server_salt, а вы можете пересчитать roll по SHA-256.

[ КАК РАБОТАЕТ PROVABLY FAIR ]
  1. Перед открытием платформа генерирует server_seed и server_salt и публикует public_hash = SHA256(server_seed + server_salt).
  2. Пользователь задаёт собственный client_seed (или используется авто-генерируемый). Открытие получает nonce — последовательный номер.
  3. В момент открытия вычисляется детерминированный roll ∈ [0, 1):
    hash = SHA256("${serverSeed}:${clientSeed}:${serverSalt}:${nonce}")
    roll = parseInt(hash.substring(0, 13), 16) / 2^52
  4. После открытия server_seed и server_salt раскрываются. Любой может пересчитать roll локально и сверить — на этой странице есть форма + JavaScript/Python референс.
  5. Подмена server_seed постфактум невозможна: public_hash был опубликован ДО открытия. Изменение хотя бы одного бита даёт другой hash.

Алгоритм идентичен для случаев, апгрейдов, контрактов и батлов — отличается только набор параметров и преобразование roll → результат.

[ ВЕРИФИКАТОР ]
Введите seeds/nonce из открытия.
[ ОТКРЫТЫЕ ВЕРОЯТНОСТИ КЕЙСОВ ]

Сумма вероятностей всегда = 100%. Вес каждого предмета фиксирован и публикуется до открытия.

[ REFERENCE-РЕАЛИЗАЦИЯ ]

Скачайте код и запустите локально — должен дать тот же roll, что и сервер.

JavaScript (WebCrypto)
// Provably Fair verification — JavaScript reference implementation
// Matches AWPBattle.com backend (apps/backend/src/common/crypto.util.ts)

async function sha256Hex(input) {
  const buffer = new TextEncoder().encode(input);
  const digest = await crypto.subtle.digest('SHA-256', buffer);
  return Array.from(new Uint8Array(digest))
    .map((b) => b.toString(16).padStart(2, '0'))
    .join('');
}

function hashToUnitFloat(hashHex) {
  const slice = hashHex.slice(0, 13);
  const intValue = parseInt(slice, 16);
  return intValue / 0x10000000000000;
}

async function computeRoll(serverSeed, clientSeed, serverSalt, nonce) {
  const message = `${serverSeed}:${clientSeed}:${serverSalt}:${nonce}`;
  const hash = await sha256Hex(message);
  return { hash, roll: hashToUnitFloat(hash) };
}

// Usage:
// computeRoll('SERVER_SEED', 'CLIENT_SEED', 'SERVER_SALT', 0).then(console.log);
Python 3 (hashlib)
# Provably Fair verification — Python reference implementation
# Matches AWPBattle.com backend (apps/backend/src/common/crypto.util.ts)

import hashlib

def hash_to_unit_float(hash_hex: str) -> float:
    return int(hash_hex[:13], 16) / 0x10000000000000

def compute_roll(server_seed: str, client_seed: str, server_salt: str, nonce: int) -> dict:
    message = f"{server_seed}:{client_seed}:{server_salt}:{nonce}"
    hash_hex = hashlib.sha256(message.encode("utf-8")).hexdigest()
    return {"hash": hash_hex, "roll": hash_to_unit_float(hash_hex)}

# Usage:
# print(compute_roll("SERVER_SEED", "CLIENT_SEED", "SERVER_SALT", 0))