如何让玩家相信游戏是公平的?
转载自:http://blog.codingnow.com/2014/02/net_gamble.html
去赌场参观过的同学应该都见过那种押大小的骰子游戏。庄家投掷三枚骰子,把骰盅盖住,玩家可以押大或小。开盅后,如果发现三个数字之和大于等于 11 就算大,小于等于 10 就算小。如果你猜对了,庄家就 1 赔 1 算给你筹码;否则输掉筹码。另外,还可以以不同赔率压数字,或压三个相同。
为了保障庄家利益,三个相同的数字算不大不小。从概率上讲,这让长时间内庄家必胜。概率分析见这里。
如果把这个游戏搬到网络上如何呢?(注意:网上赌博在很多国家是被禁止的,这里只做技术分析而已)
如何让玩家相信庄家没有作弊,真的产生了随机的骰子呢?
记得网易泡泡曾经在聊天室中做过一个简单的赌大小的文字游戏。我一同学兴致勃勃的玩过,他告诉我系统一定作弊过的。他写了个程序监控每局游戏开盅前的下注情况,到最后一秒再下住,永远下注少的一边(也就是跟庄),只花了一天时间就刷了无数泡泡币。
其实这只是游戏实现者的贪心和无知而已。其实这个游戏的规则保证了庄家利益,庄家没有必要作弊。但有些游戏设计者就是脑子转不过弯来,的确考虑过作弊。不是连六合彩这种极大化庄家利益的游戏规则都有流言暴出庄家作弊么?
那么,是不是网络版的赌大小一定得不到玩家信任呢?
其实有一个简单的方法可以向玩家证明骰子的随机性:
-
每局游戏前,先随机三个 1-6 的数字,并同时生成三个足够长(比如 80 字符, 长度在屏幕方便显示的范围即可)的文本随机串,把数字附在随机串的两端。比如随机出 2,4,5 这三个数字,就同时生成形如 2xxxxxxxxxxxxxxx2 , 4xxxxxxxxxxxxxxx4, 5xxxxxxxxxxxxxxx5 (xxxx 每次随机) 的字符串。计算这三个字符串的 md5 值,并事先通过网络展示给玩家。
-
玩家收到三个秘密串后开始下注。下注时间有限,只有几分钟的时间。由于 md5 的不可逆性,在这么短时间内,不可能知道串的原文。注:网络上所谓的 md5 破解,都是基于收集有意义的字符串的 md5 值构成海量的数据库比对查找的,并非对 md5 结果做逆运算。纯随机串的 md5 值不可能在很短时间求逆。
-
下注时间过了后,系统通过网络公布事先的三个随机数字构成的随机串,也就相当于开盅。这时候,玩家应该认赌服输了。如果他认为系统作弊,可以自行校验系统公布的串的 md5 值是否和事先公开的值相等。
如此便可证明,骰子是在玩家下注前就确定下来的,而不是根据玩家下注的行为更改让庄家获利。
没错,现在有数学证明可以在有限时间构造出另一个符合规则的串有相同的 md5 值。但那也需要相当的计算能力。如果这个网上赌场开的时间足够长,是没有那么多计算能力支撑长期的作弊的。之所以不必选用可能更安全的同类算法,是因为 md5 的普及率和认知程度最高,计算工具也随手可得而已。
如果想进一步提高信任度,让玩家相信没有提前计算出 md5 碰撞值,可以在随机的 xxxxx 中进一步加上上一局游戏的骰子 md5 值,让每次随机量都是和上一次相关的。甚至可以加上上一局游戏参与玩家的赌注金额。这样几乎不可能提交计算某一次游戏的随机串的 md5 碰撞。
关于 MD5 的碰撞构造,多个 md5 chunk 比单个 chunk 要容易的多。单 chunk 的碰撞构造在 2012 年的这篇 paperSingle-block collision attack on MD5 中提到的方法的计算复杂度在 2 的 50 次方 MD5 运算量级。不是现在普通的计算机计算能力所能承受的。
虽然不是所有玩家都可以理解这个规则,但规则容易直接在游戏中公示。服务器记录所有历史的数据供玩家备查。还是很容易取得玩家群体的信任的。