На этой странице
Блэкджек (зашифрованная версия)
На этой странице
Введение
Эта страница посвящена зашифрованной версии блэкджека, в которую часто играют в казино, использующих криптовалюту. Предполагаю, что читатель уже знаком с основными правилами традиционного блэкджека .
Казино, где доказуемая честность
Анализ
В случае с игрой на Crypto.Games, странный набор правил выглядит следующим образом:
- 4 палубы
- Перетасовка после каждой раздачи.
- Дилер не смотрит, нет ли у него блэкджека.
- Выплаты в блэкджеке составляют 6:5.
- Дилер набрал очко на Soft 17.
- Удвойте ставку на любые две карты
- Разыграйте тузы
- Досрочная капитуляция
- Десятка и туз после разделения считаются блэкджеком.
- После разделения разрешен двойной фолд
- Игрок может разделить поле только один раз (предполагаю).
Если не учитывать досрочную сдачу и 10-A после разделения, считая их как блэкджек, мой калькулятор преимущества казино в блэкджеке показывает преимущество в 1,91% при использовании базовой стратегии. Однако мой список вариантов правил блэкджека показывает, что значение двух правил, которые калькулятор не поддерживает, составляет 0,74%. Таким образом, общее преимущество казино составляет 1,17%, что довольно много для онлайн-игры в блэкджек.
Честная игра
Ниже описан процесс, который Crypto.Games использует для случайного выбора карт из четырех колод в своей игре в блэкджек.
- Перед тем как сделать ставку, игроку необходимо раскрыть хеш SHA-256 начального значения сервера.
- После того, как ставка сделана, объедините начальное значение сервера (Server Seed) и начальное значение клиента (Client Seed) в указанном порядке.
- Возьмите хеш SHA-512 объединенного начального значения из шага 1.
- Возьмите два символа из хеша, найденного на шаге 2, и посмотрите слева.
- Преобразуйте два символа из шага 3 из шестнадцатеричной системы счисления в десятичную. Если вам непонятно, о чём я говорю, я объясняю основы шестнадцатеричной системы счисления на своей странице о кубиках (зашифрованная версия).
- Если результат шага 4 равен 207 или меньше, то сопоставьте этот номер карты с конкретной картой в колоде из 208 карт.
- Если номер этой карты еще не найден в руке, сопоставьте его с конкретной игральной картой. Вот как это сделать:
- Чтобы узнать ранг карты, разделите номер карты на 13 и возьмите остаток. Сопоставьте остаток с рангом следующим образом: от 0 до туза, от 1 до 2, от 2 до 3, от 3 до 4, от 4 до 5, от 5 до 6, от 6 до 7, от 7 до 8, от 8 до 9, от 9 до 10, от 10 до валета, от 11 до дамы, от 12 до короля.
- Чтобы определить масть, разделите номер карты на 13 и отбросьте остаток. Затем разделите полученное частное на 4 и возьмите остаток. Затем сопоставьте этот остаток с мастью следующим образом: 0 — пики, 1 — червы, 2 — бубны, 3 — трефы.
- В противном случае, если результат шага 5 был больше 207 или эта карта уже была найдена, то игнорируйте эти две цифры в хеше.
- Продвиньтесь на две позиции в хешрейте, затем вернитесь к шагу 3 и продолжайте, пока не дойдете до конца хешрейта. Этого должно хватить, чтобы обработать гораздо больше карт, чем потребуется для одной раздачи в блэкджек.
Пример
Ниже показано, как работает этот процесс на примере одной раздачи.
Изображение выше, взятое из панели «Честная игра», было сделано до того, как была сделана ставка. Для обеспечения честной игры необходимо ввести и записать новый клиентский сид (подойдет набор случайных символов) и хеш следующего серверного сида, который игра называет «Следующий серверный сид SHA256». Вот они:
Начальное значение параметра клиента = 5v5b85n85vb856nvbn5vbn
- Следующий сид сервера SHA256 =
581b31f8cd6e5d4bb510ac0e53a440af7baab92f8f1f220eff14e20201e0b1f6
Лично я, если уж приходится делать это сложным способом, копирую и вставляю эти элементы в Блокнот.
На изображении выше я начинаю со ставки в 0,00001 BTC (биткоина), что эквивалентно примерно 10 центам. Игроку предлагается использовать эту ставку, чтобы купить десять фишек, а затем поставить все десять. Зачем они усложняют ситуацию этим шагом, я не знаю.
В начале игры у меня было 11 очков против 3, поэтому я удвоил ставку и получил 3. У дилера в закрытой руке была 5, в сумме 8, затем он вытянул короля, в сумме 18. Таким образом, я проиграл со счетом 14 к 18.
png" />
Далее я возвращаюсь к комиссии по честной игре, чтобы убедиться в честности игры, о чем свидетельствует предопределенный порядок карт еще до того, как я сделал ставку. Выполняя описанные выше шаги:
- На панели Fair Gaming мы видим, что начальное значение сервера (Seed) было
Yt5IDwsb3Ldc5vyusvcQNfLqqjoYmCHGRkasqXNQ. - Мы берём хеш SHA-256 и получаем 581b31f8cd6e5d4bb510ac0e53a440af7baab92f8f1f220eff14e20201e0b1f6 .
- Мы сравниваем хеш из шага 2 с "начальным значением SHA256 следующего сервера", записанным до ставки, и проверяем их совпадение. Если они не совпадают, значит, вы допустили ошибку или казино лжет/обманывает. В данном случае они совпадают. Это подтверждает, что порядок карт был предопределен.
- Чтобы убедиться, что вы получили правильные карты, объедините Server Seed и Client Seed в указанном порядке. Это даст вам Yt5IDwsb3Ldc5vyusvcQNfLqqjoYmCHGRkasqXNQ5v5b85n85vb856nvbn5vbn . Если вы выбрали использование nonce, он находится в конце Client Seed.
- Возьмите хеш SHA-512 объединенного хеша из шага 4. Почему они используют две разные хеш-функции (SHA-256 и SHA-512), я понятия не имею. Это даст вам 2b87fbc5eac7368ef393c8ab292f71a0251702f6db028ca8a855bfaa541b78df3ae996ad22ac022588a46231ed32180d5cbde86dff5d2368cbb7658332bbb9bc.
- Возьмите первые два символа, которые равны 2b , и переведите их в шестнадцатеричный формат: 2b = 2*16 + 11 = 43.
- Поскольку 43 <= 207, преобразуем его в карту: ранг = mod(43,13) = 4, что соответствует 5. Масть = mod(int(43/13),4) = mod(3,4) = 3, что соответствует трефам. Это первая карта, сданная игроку, — пятерка треф.
- Переместитесь на две позиции в хеш-таблице из шага 4, что соответствует числу 87. Преобразуйте это число из шестнадцатеричного в десятичное: 8*16 + 7 = 135.
- Поскольку 135 <= 207 и еще не найдено, преобразуйте его в карту: ранг = mod(135,13) = 5, что соответствует 6. Масть = mod(int(135/13),4) = mod(10,4) = 2, что соответствует бубнам. Это вторая карта, сданная игроку, шестерка бубен.
- Переместитесь на две позиции в хеш-таблице из шага 4, это будет fb . Преобразуйте это значение из шестнадцатеричного в десятичное: 15*16 + 11 = 251.
- Поскольку 251 > 207, мы пропускаем эти две позиции.
- Переместитесь на две позиции в хеш-таблице из шага 4, это c5 . Преобразуйте это значение из шестнадцатеричного в десятичное: 12*16 + 5 = 197.
- Поскольку 197 <= 207 и еще не найдено, преобразуйте его в карту: ранг = mod(197,13) = 2, что соответствует рангу 3. Масть = mod(int(197/13),4) = mod(15,4) = 3, что соответствует трефам. Это первая (открытая) карта, сданная дилеру, — тройка треф.
- Переместитесь на две позиции в хеш-таблице из шага 4, то есть ea . Преобразуйте это из шестнадцатеричного числа в десятичное: 14*16 + 10 = 234.
- Поскольку 234 > 207, мы пропускаем эти две позиции.
- Переместитесь на две позиции в хеш-таблице из шага 4, это c7 . Преобразуйте это значение из шестнадцатеричного в десятичное: 12*16 + 7 = 199.
- Поскольку 199 <= 207 и еще не найдено, преобразуйте его в карту: ранг = mod(199,13) = 4, что соответствует 5. Масть = mod(int(199/13),4) = mod(15,4) = 3, что соответствует трефам. Это вторая (рубашками вниз) карта, сданная дилеру, — пятерка треф.
- Переместитесь на две позиции в хеш-таблице из шага 4, что соответствует числу 36. Преобразуйте это число из шестнадцатеричного в десятичное: 3*16 + 6 = 54.
- Поскольку 54 <= 207 и еще не найдено, преобразуем его в карту: ранг = mod(54,13) = 2, что соответствует 3. Масть = mod(int(54/13),4) = mod(4,4) = 0, что соответствует пикам. Эта тройка пик — следующая карта в колоде, которая досталась игроку после удвоения ставки. Таким образом, сумма очков игрока составляет 5+6+3 = 14.
- Переместитесь на две позиции в хеш-таблице из шага 4, что соответствует 8e . Преобразуйте это значение из шестнадцатеричного в десятичное: 8*16 + 14 = 142.
- Поскольку 142 <= 207 и еще не найдено, преобразуем его в карту: ранг = mod(142,13) = 12, что соответствует королю. Масть = mod(int(142/13),4) = mod(10,4) = 2, что соответствует бубнам. Это, король бубен, следующая карта в колоде, которая досталась дилеру, когда ему пришлось брать дополнительную карту при наличии жесткой восьмерки, получив в сумме 18.
- Игрок проигрывает со счетом 14:18.
- Если потребуется больше карт, мы будем продолжать этот процесс до тех пор, пока не будет найдено достаточное количество карт.
Если вам кажется, что это слишком много шагов, я согласен. Именно поэтому я написал PHP-скрипт, который сделает это за вас! Чтобы использовать его, выполните следующие действия:
- Перейдите в PHP Sandbox .
- Введите начальное значение сервера (Server Seed) в строке 3.
- Введите начальные данные клиента в строке 4.
- Введите хеш следующего начального значения сервера в строке 5.
- Нажмите «Выполнить код».
Программа будет сверять хеши серверного начального значения с теми, которые были предоставлены до того, как вы сделали ставку, и с картами, розданными в игре.
У меня также есть копия кода, которую вы можете посмотреть, нажав на кнопку ниже.
[спойлер]
// Проверка честности блэкджека для Crypto.Games
$server_seed = "Yt5IDwsb3Ldc5vyusvcQNfLqqjoYmCHGRkasqXNQ";
$client_seed = "5v5b85n85vb856nvbn5vbn";
$next_hash = "581b31f8cd6e5d4bb510ac0e53a440af7baab92f8f1f220eff14e20201e0b1f6";
$rank_array=array("A",2,3,4,5,6,7,8,9,10,"J","Q","K");
$suit_array=array("пики","сердца","бубны","трефы");
$cards_found=0;
$position=0;
$combined_seed = $server_seed.$client_seed;
echo "Объединенное начальное значение = $combined_seed\n";
$combined_hash = hash('sha512', $combined_seed);
echo "Хэш объединенного начального значения = $combined_hash\n";
делать
{
$first_two=substr($combined_hash,$position,2);
$hex_to_dec=hexdec($first_two);
если ($hex_to_dec <=207)
{
$repeat=0;
если ($cards_found>0)
{
for ($i=0; $i<$cards_found; $i++)
{
if ( $hex_to_dec == $card_array[$i])
{ $repeat=1; }
}
}
если ($repeat==0)
{
$card_array[$cards_found] = $hex_to_dec;
$cards_found++;
$rank=$hex_to_dec%13;
$suit=intdiv($hex_to_dec,13)%4;
echo "Карта $cards_found = \t$rank_array[$rank] из $suit_array[$suit]\n";
}
}
$position+=2;
если ($position==128)
{
echo "Ошибка -- В хеше больше нет пробела.\n";
$cards_found=10;
}
}
пока ($cards_found<20);
$server_seed_hash=hash('sha256', $server_seed);
если ($server_seed_hash==$next_hash)
{ echo "Совпадение начального значения сервера.\n"; }
еще
{
echo "НЕСООТВЕТСТВИЕ СЕМЕННЫХ ЗНАЧЕНИЙ СЕРВЕРА!\n";
echo "Серверный начальный параметр =\t$server_seed\n";
echo "Хэш начального значения сервера =\t$server_seed_hash\n";
echo "Предполагаемый следующий хеш=\t$next_hash\n";
}
// Процедура
// 1. Установите значение «шаг» равным 0, а значение «позиция» — равным 0.
// 2. Объедините начальные значения сервера и клиента, шаг и начальное значение сервера в указанном порядке.
// 3. Сгенерируйте хеш SHA-512 строки из шага 2.
// 4. Преобразуйте первые два символа, начиная с "позиции" хеша из шага 3, из шестнадцатеричного формата в десятичный.
// 5. Если результат шага 4 равен 0–207, то сопоставьте его с конкретной картой в колоде из четырех карт.
// 6. Если результат из шага 5 уже получен, то это будет следующая карта, которая будет роздана в игре.
// 7. Чтобы преобразовать позицию карты из шага 6 в фактическую карту, выполните следующие действия:
// А. Разделите результат из шага 4 на 13 и возьмите остаток.
// B. Сопоставьте результат шага 7A, чтобы получить ранг следующим образом: от 0 до A, от 1 до 2, от 2 до 3, ..., от 9 до 10, от 10 до J, от 11 до Q, от 12 до K.
// C. Разделите результат из шага 4 на 13 и отбросьте остаток.
// D. Разделите результат из шага 7C на 4 и возьмите остаток.
// E. Сопоставьте результат из шага 7D, чтобы получить масть следующим образом: 0 — пики, 1 — червы, 2 — бубны, 3 — трефы.
// 8. Повторяйте шаги с 4 по 7, пока не дойдете до конца хеша, хотя вряд ли такое количество карт понадобится в игре.
?>
[/спойлер]

