Игры Профиль Чат Бонус Еще
Режим
Server seed
Client seed
Salt
Количество мин

Перевод сидов в байты


HMAC_SHA512(SHA256(server_seed:salt), client_seed:0)
78959b80b46d56735b3aec5912935fe2b8cb7d4a2637d2e1ae4f72129862b335f712c3ba35dcb29cba9dd4f206df877ebcf2113bcbf9f7d410772a805a2a04bd
12014915512818010986115915823689181479522618420312574385521022517479114181529817953247181951865322017815618615721224262231351261882421759203249247212161194212890424189
HMAC_SHA512(SHA256(server_seed:salt), client_seed:1)
8c62160b2bc4978d41f545a690c72fb9115e839ee6a6e2b2f9f79e4d32d91ac35509e9c0427f1330b8eeec2e58fb9b906b460ba16c90eaa460fbc697a04bf7a6
140982211431961511416524569166144199471851794131158230166226178249247158775021726195859233192661271948184238236468825115514410770111611081442341649625119815116075247166
HMAC_SHA512(SHA256(server_seed:salt), client_seed:2)
ec12aff10fe46620beb2a078361a5c5b8769c69d843216043c2d4511b2f2b8b39eb7ed3cf13f26894d625a770fd7622a014e04a730b142498714b2d1ef009b65
2361817524115228102321901781601205426929113510519815713250224604569171782421841791581832376024163381377798901191521598421784167481776673135201782092390155101
Калькулятор SHA256 Калькулятор HMAC-SHA512

Перевод байтов в числа


(120, 149, 155, 128, 180, 109, 86, 115) -> [0, ..., 24] = 11
0.468750000000000000(120 / (256 ^ 1))
+0.002273559570312500(149 / (256 ^ 2))
+0.000009238719940186(155 / (256 ^ 3))
+0.000000029802322388(128 / (256 ^ 4))
+0.000000000163709046(180 / (256 ^ 5))
+0.000000000000387246(109 / (256 ^ 6))
+0.000000000000001193(086 / (256 ^ 7))
+0.000000000000000006(115 / (256 ^ 8))
=0.471032828256672587(* 25)
=11.775820706416814332
(91, 58, 236, 89, 18, 147, 95, 226) -> [0, ..., 23] = 8
0.355468750000000000(091 / (256 ^ 1))
+0.000885009765625000(058 / (256 ^ 2))
+0.000014066696166992(236 / (256 ^ 3))
+0.000000020721927285(089 / (256 ^ 4))
+0.000000000016370905(018 / (256 ^ 5))
+0.000000000000522249(147 / (256 ^ 6))
+0.000000000000001318(095 / (256 ^ 7))
+0.000000000000000012(226 / (256 ^ 8))
=0.356367847200613763(* 24)
=8.552828332814730317
(184, 203, 125, 74, 38, 55, 210, 225) -> [0, ..., 22] = 16
0.718750000000000000(184 / (256 ^ 1))
+0.003097534179687500(203 / (256 ^ 2))
+0.000007450580596924(125 / (256 ^ 3))
+0.000000017229467630(074 / (256 ^ 4))
+0.000000000034560799(038 / (256 ^ 5))
+0.000000000000195399(055 / (256 ^ 6))
+0.000000000000002914(210 / (256 ^ 7))
+0.000000000000000012(225 / (256 ^ 8))
=0.721855002024511139(* 23)
=16.602665046563757301
(174, 79, 114, 18, 152, 98, 179, 53) -> [0, ..., 21] = 14
0.679687500000000000(174 / (256 ^ 1))
+0.001205444335937500(079 / (256 ^ 2))
+0.000006794929504395(114 / (256 ^ 3))
+0.000000004190951586(018 / (256 ^ 4))
+0.000000000138243195(152 / (256 ^ 5))
+0.000000000000348166(098 / (256 ^ 6))
+0.000000000000002484(179 / (256 ^ 7))
+0.000000000000000003(053 / (256 ^ 8))
=0.680899743594987283(* 22)
=14.979794359089719791
(247, 18, 195, 186, 53, 220, 178, 156) -> [0, ..., 20] = 20
0.964843750000000000(247 / (256 ^ 1))
+0.000274658203125000(018 / (256 ^ 2))
+0.000011622905731201(195 / (256 ^ 3))
+0.000000043306499720(186 / (256 ^ 4))
+0.000000000048203219(053 / (256 ^ 5))
+0.000000000000781597(220 / (256 ^ 6))
+0.000000000000002470(178 / (256 ^ 7))
+0.000000000000000008(156 / (256 ^ 8))
=0.965130074464343179(* 21)
=20.267731563751205215
(186, 157, 212, 242, 6, 223, 135, 126) -> [0, ..., 19] = 14
0.726562500000000000(186 / (256 ^ 1))
+0.002395629882812500(157 / (256 ^ 2))
+0.000012636184692383(212 / (256 ^ 3))
+0.000000056345015764(242 / (256 ^ 4))
+0.000000000005456968(006 / (256 ^ 5))
+0.000000000000792255(223 / (256 ^ 6))
+0.000000000000001874(135 / (256 ^ 7))
+0.000000000000000007(126 / (256 ^ 8))
=0.728970822418771758(* 20)
=14.579416448375434712
(188, 242, 17, 59, 203, 249, 247, 212) -> [0, ..., 18] = 14
0.734375000000000000(188 / (256 ^ 1))
+0.003692626953125000(242 / (256 ^ 2))
+0.000001013278961182(017 / (256 ^ 3))
+0.000000013737007976(059 / (256 ^ 4))
+0.000000000184627424(203 / (256 ^ 5))
+0.000000000000884626(249 / (256 ^ 6))
+0.000000000000003428(247 / (256 ^ 7))
+0.000000000000000011(212 / (256 ^ 8))
=0.738068654154609649(* 19)
=14.023304428937583666
(16, 119, 42, 128, 90, 42, 4, 189) -> [0, ..., 17] = 1
0.062500000000000000(016 / (256 ^ 1))
+0.001815795898437500(119 / (256 ^ 2))
+0.000002503395080566(042 / (256 ^ 3))
+0.000000029802322388(128 / (256 ^ 4))
+0.000000000081854523(090 / (256 ^ 5))
+0.000000000000149214(042 / (256 ^ 6))
+0.000000000000000056(004 / (256 ^ 7))
+0.000000000000000010(189 / (256 ^ 8))
=0.064318329177844261(* 18)
=1.157729925201196775
(140, 98, 22, 11, 43, 196, 151, 141) -> [0, ..., 16] = 9
0.546875000000000000(140 / (256 ^ 1))
+0.001495361328125000(098 / (256 ^ 2))
+0.000001311302185059(022 / (256 ^ 3))
+0.000000002561137080(011 / (256 ^ 4))
+0.000000000039108272(043 / (256 ^ 5))
+0.000000000000696332(196 / (256 ^ 6))
+0.000000000000002096(151 / (256 ^ 7))
+0.000000000000000008(141 / (256 ^ 8))
=0.548371675231253852(* 17)
=9.322318478931315155
(65, 245, 69, 166, 144, 199, 47, 185) -> [0, ..., 15] = 4
0.253906250000000000(065 / (256 ^ 1))
+0.003738403320312500(245 / (256 ^ 2))
+0.000004112720489502(069 / (256 ^ 3))
+0.000000038649886847(166 / (256 ^ 4))
+0.000000000130967237(144 / (256 ^ 5))
+0.000000000000706990(199 / (256 ^ 6))
+0.000000000000000652(047 / (256 ^ 7))
+0.000000000000000010(185 / (256 ^ 8))
=0.257648804822363742(* 16)
=4.122380877157819867
(17, 94, 131, 158, 230, 166, 226, 178) -> [0, ..., 14] = 1
0.066406250000000000(017 / (256 ^ 1))
+0.001434326171875000(094 / (256 ^ 2))
+0.000007808208465576(131 / (256 ^ 3))
+0.000000036787241697(158 / (256 ^ 4))
+0.000000000209183781(230 / (256 ^ 5))
+0.000000000000589750(166 / (256 ^ 6))
+0.000000000000003136(226 / (256 ^ 7))
+0.000000000000000010(178 / (256 ^ 8))
=0.067848421377358956(* 15)
=1.017726320660384376
(249, 247, 158, 77, 50, 217, 26, 195) -> [0, ..., 13] = 13
0.972656250000000000(249 / (256 ^ 1))
+0.003768920898437500(247 / (256 ^ 2))
+0.000009417533874512(158 / (256 ^ 3))
+0.000000017927959561(077 / (256 ^ 4))
+0.000000000045474735(050 / (256 ^ 5))
+0.000000000000770939(217 / (256 ^ 6))
+0.000000000000000361(026 / (256 ^ 7))
+0.000000000000000011(195 / (256 ^ 8))
=0.976434606406517580(* 14)
=13.670084489691246787
(85, 9, 233, 192, 66, 127, 19, 48) -> [0, ..., 12] = 4
0.332031250000000000(085 / (256 ^ 1))
+0.000137329101562500(009 / (256 ^ 2))
+0.000013887882232666(233 / (256 ^ 3))
+0.000000044703483582(192 / (256 ^ 4))
+0.000000000060026650(066 / (256 ^ 5))
+0.000000000000451195(127 / (256 ^ 6))
+0.000000000000000264(019 / (256 ^ 7))
+0.000000000000000003(048 / (256 ^ 8))
=0.332182511747756870(* 13)
=4.318372652720839255
(184, 238, 236, 46, 88, 251, 155, 144) -> [0, ..., 11] = 8
0.718750000000000000(184 / (256 ^ 1))
+0.003631591796875000(238 / (256 ^ 2))
+0.000014066696166992(236 / (256 ^ 3))
+0.000000010710209608(046 / (256 ^ 4))
+0.000000000080035534(088 / (256 ^ 5))
+0.000000000000891731(251 / (256 ^ 6))
+0.000000000000002151(155 / (256 ^ 7))
+0.000000000000000008(144 / (256 ^ 8))
=0.722395669284180975(* 12)
=8.668748031410171251
(107, 70, 11, 161, 108, 144, 234, 164) -> [0, ..., 10] = 4
0.417968750000000000(107 / (256 ^ 1))
+0.001068115234375000(070 / (256 ^ 2))
+0.000000655651092529(011 / (256 ^ 3))
+0.000000037485733628(161 / (256 ^ 4))
+0.000000000098225428(108 / (256 ^ 5))
+0.000000000000511591(144 / (256 ^ 6))
+0.000000000000003247(234 / (256 ^ 7))
+0.000000000000000009(164 / (256 ^ 8))
=0.419037558469941396(* 11)
=4.609413143169355465
(96, 251, 198, 151, 160, 75, 247, 166) -> [0, ..., 9] = 3
0.375000000000000000(096 / (256 ^ 1))
+0.003829956054687500(251 / (256 ^ 2))
+0.000011801719665527(198 / (256 ^ 3))
+0.000000035157427192(151 / (256 ^ 4))
+0.000000000145519152(160 / (256 ^ 5))
+0.000000000000266454(075 / (256 ^ 6))
+0.000000000000003428(247 / (256 ^ 7))
+0.000000000000000009(166 / (256 ^ 8))
=0.378841793077569267(* 10)
=3.788417930775692888
(236, 18, 175, 241, 15, 228, 102, 32) -> [0, ..., 8] = 8
0.921875000000000000(236 / (256 ^ 1))
+0.000274658203125000(018 / (256 ^ 2))
+0.000010430812835693(175 / (256 ^ 3))
+0.000000056112185121(241 / (256 ^ 4))
+0.000000000013642421(015 / (256 ^ 5))
+0.000000000000810019(228 / (256 ^ 6))
+0.000000000000001416(102 / (256 ^ 7))
+0.000000000000000002(032 / (256 ^ 8))
=0.922160145142599696(* 9)
=8.299441306283396713
(190, 178, 160, 120, 54, 26, 92, 91) -> [0, ..., 7] = 5
0.742187500000000000(190 / (256 ^ 1))
+0.002716064453125000(178 / (256 ^ 2))
+0.000009536743164063(160 / (256 ^ 3))
+0.000000027939677238(120 / (256 ^ 4))
+0.000000000049112714(054 / (256 ^ 5))
+0.000000000000092371(026 / (256 ^ 6))
+0.000000000000001277(092 / (256 ^ 7))
+0.000000000000000005(091 / (256 ^ 8))
=0.744913129185172718(* 8)
=5.959305033481381741
(135, 105, 198, 157, 132, 50, 22, 4) -> [0, ..., 6] = 3
0.527343750000000000(135 / (256 ^ 1))
+0.001602172851562500(105 / (256 ^ 2))
+0.000011801719665527(198 / (256 ^ 3))
+0.000000036554411054(157 / (256 ^ 4))
+0.000000000120053301(132 / (256 ^ 5))
+0.000000000000177636(050 / (256 ^ 6))
+0.000000000000000305(022 / (256 ^ 7))
+0.000000000000000000(004 / (256 ^ 8))
=0.528957761245870350(* 7)
=3.702704328721092342
(60, 45, 69, 17, 178, 242, 184, 179) -> [0, ..., 5] = 1
0.234375000000000000(060 / (256 ^ 1))
+0.000686645507812500(045 / (256 ^ 2))
+0.000004112720489502(069 / (256 ^ 3))
+0.000000003958120942(017 / (256 ^ 4))
+0.000000000161890057(178 / (256 ^ 5))
+0.000000000000859757(242 / (256 ^ 6))
+0.000000000000002554(184 / (256 ^ 7))
+0.000000000000000010(179 / (256 ^ 8))
=0.235065762349175311(* 6)
=1.410394574095051867
(158, 183, 237, 60, 241, 63, 38, 137) -> [0, ..., 4] = 3
0.617187500000000000(158 / (256 ^ 1))
+0.002792358398437500(183 / (256 ^ 2))
+0.000014126300811768(237 / (256 ^ 3))
+0.000000013969838619(060 / (256 ^ 4))
+0.000000000219188223(241 / (256 ^ 5))
+0.000000000000223821(063 / (256 ^ 6))
+0.000000000000000527(038 / (256 ^ 7))
+0.000000000000000007(137 / (256 ^ 8))
=0.619993998888500486(* 5)
=3.099969994442502319
(77, 98, 90, 119, 15, 215, 98, 42) -> [0, ..., 3] = 1
0.300781250000000000(077 / (256 ^ 1))
+0.001495361328125000(098 / (256 ^ 2))
+0.000005364418029785(090 / (256 ^ 3))
+0.000000027706846595(119 / (256 ^ 4))
+0.000000000013642421(015 / (256 ^ 5))
+0.000000000000763833(215 / (256 ^ 6))
+0.000000000000001360(098 / (256 ^ 7))
+0.000000000000000002(042 / (256 ^ 8))
=0.302282003467408966(* 4)
=1.209128013869635865
(1, 78, 4, 167, 48, 177, 66, 73) -> [0, ..., 2] = 0
0.003906250000000000(001 / (256 ^ 1))
+0.001190185546875000(078 / (256 ^ 2))
+0.000000238418579102(004 / (256 ^ 3))
+0.000000038882717490(167 / (256 ^ 4))
+0.000000000043655746(048 / (256 ^ 5))
+0.000000000000628830(177 / (256 ^ 6))
+0.000000000000000916(066 / (256 ^ 7))
+0.000000000000000004(073 / (256 ^ 8))
=0.005096712892457088(* 3)
=0.015290138677371265
(135, 20, 178, 209, 239, 0, 155, 101) -> [0, ..., 1] = 1
0.527343750000000000(135 / (256 ^ 1))
+0.000305175781250000(020 / (256 ^ 2))
+0.000010609626770020(178 / (256 ^ 3))
+0.000000048661604524(209 / (256 ^ 4))
+0.000000000217369234(239 / (256 ^ 5))
+0.000000000000000000(000 / (256 ^ 6))
+0.000000000000002151(155 / (256 ^ 7))
+0.000000000000000005(101 / (256 ^ 8))
=0.527659584286995886(* 2)
=1.055319168573991773

Перевести числа в результат – как это сделать?


В прошлом шаге было получено 24 числа, они будут называться основным массивом в интервале от 0 до 1. Переводим их в позиции мин при помощи специального алгоритма Фишера-Йетса.

Создадим 2 массива: исходный массив, содержащий в порядке следования числа от 0 до 24, и пустой массив-перестановку, в который по мере работы алгоритма будем "перекладывать" элементы из первого массива, таким образом создавая случайную перестановку.На каждом шаге будем перекладывать один элемент из исходного массива в конец массива-перестановки. Позицию элемента, выбираемого из исходного массива, будем определять как произведениСоздается два дополнительных массива: исходный, который содержит числа от 0 до 24 по порядку и полностью пустой массив-перестановку, где алгоритм по мере своей работы будет переставлять элементы из основного массива, что приведет к созданию случайной перестановки чисел. Как итог: мы получаем 24 шага и 24 элемента на перестановку, где первый элемент – это позиция для мины, а второй – вторая мина. К примеру, если в игре присутствует лишь 3 мины, то их местонахождение приравнивается к трем элементам из этой же рокировки.

Счет ячеек на минном поле идет с левого верхнего угла (позиция #0), слева направо, сверху вниз (нижняя правая ячейка - позиция #24).

Шаг Элемент индексного массива Исходный массив Перестановка
1 11 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] [11]
2 8 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] [11, 8]
3 16 [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24] [11, 8, 18]
4 14 [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23, 24] [11, 8, 18, 16]
5 20 [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 17, 19, 20, 21, 22, 23, 24] [11, 8, 18, 16, 24]
6 14 [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 17, 19, 20, 21, 22, 23] [11, 8, 18, 16, 24, 17]
7 14 [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 19, 20, 21, 22, 23] [11, 8, 18, 16, 24, 17, 19]
8 1 [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 20, 21, 22, 23] [11, 8, 18, 16, 24, 17, 19, 1]
9 9 [0, 2, 3, 4, 5, 6, 7, 9, 10, 12, 13, 14, 15, 20, 21, 22, 23] [11, 8, 18, 16, 24, 17, 19, 1, 12]
10 4 [0, 2, 3, 4, 5, 6, 7, 9, 10, 13, 14, 15, 20, 21, 22, 23] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5]
11 1 [0, 2, 3, 4, 6, 7, 9, 10, 13, 14, 15, 20, 21, 22, 23] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2]
12 13 [0, 3, 4, 6, 7, 9, 10, 13, 14, 15, 20, 21, 22, 23] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23]
13 4 [0, 3, 4, 6, 7, 9, 10, 13, 14, 15, 20, 21, 22] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7]
14 8 [0, 3, 4, 6, 9, 10, 13, 14, 15, 20, 21, 22] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15]
15 4 [0, 3, 4, 6, 9, 10, 13, 14, 20, 21, 22] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15, 9]
16 3 [0, 3, 4, 6, 10, 13, 14, 20, 21, 22] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15, 9, 6]
17 8 [0, 3, 4, 10, 13, 14, 20, 21, 22] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15, 9, 6, 22]
18 5 [0, 3, 4, 10, 13, 14, 20, 21] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15, 9, 6, 22, 14]
19 3 [0, 3, 4, 10, 13, 20, 21] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15, 9, 6, 22, 14, 10]
20 1 [0, 3, 4, 13, 20, 21] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15, 9, 6, 22, 14, 10, 3]
21 3 [0, 4, 13, 20, 21] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15, 9, 6, 22, 14, 10, 3, 20]
22 1 [0, 4, 13, 21] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15, 9, 6, 22, 14, 10, 3, 20, 4]
23 0 [0, 13, 21] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15, 9, 6, 22, 14, 10, 3, 20, 4, 0]
24 1 [13, 21] [11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15, 9, 6, 22, 14, 10, 3, 20, 4, 0, 21]
Итог
[11, 8, 18, 16, 24, 17, 19, 1, 12, 5, 2, 23, 7, 15, 9, 6, 22, 14, 10, 3, 20, 4, 0, 21]

Числа, которые подсвечены зеленым в таблице, указывают на позиции, в которых находились мины. Вкладка «Реализация» ознакомит Вас с работой алгоритма подробнее.

Доказуемая честность


Основополагающая концепция доказуемой честности заключается в том, что игроки имеют возможность доказать и подтвердить, что результаты их игр являются честными и не подвергались манипуляциям со стороны сайта. Это достигается за счет использования так называемой схемы обязательства, где случайные результаты игр генерируются на основе набора параметров, часть которых известна игроку перед началом раунда. Схема обязательства используется, чтобы гарантировать, что игрок оказывает влияние на все полученные результаты, вместе с тем параметры подобраны таким образом, чтобы игрок не мог предугадать результат той или иной игры наперед, но всегда мог детерминированным образом подтвердить факт честности данной игры.

Параметры генератора случайных чисел


В предложенной системе в качестве входных параметров генератора случайных чисел используется следующий набор из четырех параметров

Server seed

Серверный сид генерируется нашей системой и представляет собой 32 байта, представленные в виде 64-символьной строки. Для режимов, в которых в одном раунде участвует только один игрок, у игрока есть возможность запросить у системы генерацию нового серверного сида, новое значение которого будет сразу же показано. К этим режимам относятся:

  • Mines
  • Dice

Для режимов, в которых в одном раунде участвуют несколько игроков, у отдельного игрока нет возможности запросить у системы генерацию нового серверного сида (это вызвано тем, что системе неясно, запрос какого из игроков удовлетворить), однако гарантией честности в данных режимах является тот факт, что серверный сид является постоянным, то есть не меняется от раунда к раунду. В качестве значения серверного сида взят заранее посчитанный хеш определенного bitcoin-блока. Режимы и соответствующие им постоянные серверные сиды приведены ниже:

Client seed

Клиентский сид принадлежит игроку и используется для того, чтобы игрок имел возможность оказывать влияние на генерируемые числа. Изначально клиентский сид генерируется системой при регистрации на сайте, однако в любой момент у пользователя есть возможность сменить свой клиентский сид (обратите внимание, что, в отличие от серверного сида, есть возможность ввести значение желаемого клиентского сида). Для режимов, в которых в одном раунде участвует только один игрок, в качестве клиентского сида используется пользовательский клиентский сид. Эти режимы приведены ниже:

  • Mines
  • Dice

Для режимов, в которых в одном раунде участвуют несколько игроков, в качестве клиентского сида не может использоваться пользовательский клиентский сид (это вызвано тем, что системе неясно, сид какого из игроков использовать), однако гарантией честности в данных режимах является тот факт, что клиентский сид является постоянным, то есть не меняется от раунда к раунду. В качестве значения клиентского сида взят заранее посчитанный хеш определенного bitcoin-блока. Режимы и соответствующие им постоянные клиентские сиды приведены ниже:

Salt

Поскольку серверный сид и клиентский сид постоянны и известны пользователю, параметр salt (соль) используется в схеме для того, чтобы получать разные результаты с одной и той же парой client seed + server seed. Соль представляет собой случайные 32 байта, представленные в виде 64-символьной строки. Данный параметр уникален для каждого раунда и недоступен игроку перед началом игры, однако отображается в конце игры (так называемая фаза раскрытия в схеме обязательства).

Cursor

Генератор случайных чисел, используя в качестве входных параметров server seed, client seed и salt, генерирует случайные 64 байта, представленные в виде 128-символьной строки. Эта строка используется для генерации 8 случайных чисел. Однако некоторые режимы требуют генерации большего количества чисел. Для этого вводится дополнительный параметр cursor, который изначательно равен 0 и увеличивается на единицу каждый раз, когда необходимо сгенерировать очередные 8 чисел в рамках одного раунда. Режимы, которые используют больше одного курсора:

  • Mines (3 курсора)

Режимы, которые используют ровно один курсор:

  • Dice
  • Double
  • Jackpot
  • Crash

Генератор случайных чисел


Генерация случайных байт на основе входных параметров осуществляется с использованием функций HMAC-SHA512 и SHA256

bytes = HMAC-SHA512(SHA256(server_seed:salt), client_seed:cursor)

Результатом генерации являются случайные 64 байта, которые затем делятся на 8 блоков по 8 байт, и каждый блок используется для генерации случайного числа в диапазоне [0, 1). Алгоритм конвертации блока в число приведен в разделе "Реализация", а также графически демонстрируется при проверке игры.

Батарея тестов Dieharder


Батарея тестов Dieharder — это набор статистических тестов для измерения качества генератора случайных чисел. Она состоит из множества тестов (включая набор тестов Diehard и набор тестов NIST Test Suite), которые вместе рассматриваются как один из наиболее строгих существующих наборов тестов. Мы сгенерировали 1 миллиард случайных чисел с помощью вышеприведенного генератора и протестировали этот набор с помощью Dieharder со следующими опциями

dieharder -g 202 -f ./rng_output_test_random_CS -a |& tee -a output_dh_random_CS.txt

Для большей статистической значимости мы запустили тест дважды на разных наборах. Результаты тестирования показывают, что приведенный генератор случайных чисел действительно генерирует несмещенные случайные последовательности, в которых отсутствуют статистически значимые закономерности. Отчеты в виде текстовых файлов доступны по ссылкам:
output_dh_random_CS_1.txt
output_dh_random_CS_2.txt

Генерация случайных чисел


Для любого раунда, client seed, server seed, salt и cursor служат единственными входными параметрами генератора. Генератор преобразует эти параметры в последовательность случайных байтов с помощью хеш-функций HMAC-SHA512 и SHA256, используя свойство лавинного эффекта

function seedsToBytes(serverSeed, clientSeed, salt, cursor) {
    // SHA-256 calculation
    const hmacKey = createHash(serverSeed + ":" + salt);
    const hmacMessage = clientSeed + ":" + cursor;
    // HMAC calculation
    return createHmac(hmacKey, hmacMessage);
}

Перевод байтов в числа


Результатом работы генератора являются 64 случайных байта (128-символьная строка), которые разбиваются на 8 блоков по 8 байт каждый, и каждый блок используется для получения одного числа в интервале [0, 1) с помощью нижеприведенного алгоритма.

function numbersFromBytes(bytes) {
    for (let t = 0; t < 8; t++) {
        let value = 0;
        let pw = 256;
        for (let i = t * 8; i < t * 8 + 8; i++) {
            value += bytes[i] / pw;
            pw *= 256;
        }
        result.push(value);
    }
    return result;
}

Генерация результата Mines


Для генерации результата в режиме Mines требуется 24 случайных числа в интервале [0..1), поэтому генерируется 3 массива из 8 чисел, которые затем объединяются в один массив, называемый индексным. Данный массив используется для выбора позиций мин на поле с помощью алгоритма Фишера-Йетса

// numbers - index array
function minesShuffling(numbers, minesCount) {
    // Initial array
    let range = [];
    // Resulting array
    let permutation = [];
    for (var i = 0; i <= 24; i++) range.push(i);
    for (var i = 0; i < numbers.length; i++) { 
        let index = Math.floor(numbers[i] * range.length);
        permutation.push(range.splice(index, 1)[0]);
    }
    return permutation;
}

Генерация результата Dice


Для генерации результата в режиме Dice требуется 1 случайное число в интервале [0..1), которое затем переводится в результат Dice в интервале [0..100] по следующему алгоритму.

// number has interval [0..1)
function diceOutcome(number) {
    return Math.floor(number * 10001) / 100;
}

Генерация результата Double


Для генерации результата в режиме Double требуется 1 случайное число в интервале [0..1), которое затем переводится в сектор колеса в интервале [0..14] по следующему алгоритму.

// number has interval [0..1)
function doubleOutcome(number) {
    return Math.floor(number * 15);
}

Генерация результата Jackpot


Для генерации результата в режиме Jackpot требуется 1 случайное число в интервале [0..1), которое затем переводится в выигрышный билет путем арифметического умножения на общее число билетов, округленного вниз, с поправкой на единицу (поскольку нумерация билетов начинается с 1).

// number has interval [0..1)
function jackpotOutcome(number, ticketsCount) {
    return Math.floor(number * ticketsCount) + 1;
}

Генерация результата Crash


Для генерации результата в режиме Crash требуется 1 случайное число в интервале [0..1), которое затем переводится в коэффициент Crash, имеющий экспоненциальное распределение, по следующему алгоритму.

// number has interval [0..1)
function crashOutcome(number) {
    return max(1, 1000000 / (Math.floor(number * 1000000) + 1) * (1 - 0.05)).toFixed(2);
}
Онлайн чат
Александр Синицын
Надеюсь меня тоже на стриме засвечусь)))
Лёша Кузнецов
Беспредельный Слава, что ты творишь
Дмитрий Поляк
Ребят где можно 700 монет нафармить?
Максим Сазанов
xD
Дмитрий Крайнов
дайс че то сегодня подозрительно выдавать начал, как-то странно. уже +500р за час
Nicolas Adamenko
зашел купить маме подарок
Артём Завсеголов
краш некст 0 будет
Евгений Безпалива
зашел купить маме подарок
Андрей Борищенко
краш некст 0 будет
Вероничка Мащенко
Надеюсь меня тоже на стриме засвечусь)))
Евгений Шлямин
дабл 100 на черное 10 на заеленое сейчас!
Евгений Морозов
краш выдает сегодня, ухх
Семён Азбель
Скрип скрип))
Стас Тукмачёв
краш выдает сегодня, ухх
Alex ru_1
Да ну нахер 5 раз слило на 80% прикиньте надайсе подряд такоедерьмо слил 10монетпотомсто потлм 500 потом 1000 потом 2000 это капец
Рубен Нариманов
краш некст 0 будет
Влада Петрова
Да ну нахер 5 раз слило на 80% прикиньте надайсе подряд такоедерьмо слил 10монетпотомсто потлм 500 потом 1000 потом 2000 это капец
Евгений Безпалива
Да ну нахер 5 раз слило на 80% прикиньте надайсе подряд такоедерьмо слил 10монетпотомсто потлм 500 потом 1000 потом 2000 это капец
Дмитрий Красиков
блин у него чат закрыт(((
Георгий Шайн
Да ну нахер 5 раз слило на 80% прикиньте надайсе подряд такоедерьмо слил 10монетпотомсто потлм 500 потом 1000 потом 2000 это капец
0