java 的api中有伪随机数产生方法,概况:
Math.random()方法,java.util.Random类。和 java.util.Random 的子类强随机数 java.security.SecureRandom。
基本知识一:
1. 因为Math.random()方法也是基于java.util.Random类通过调用Random.nextDouble() 来实现的,所以这里只参考java.util.Random类。
Random类中随机数字产生,如果指定种子数就从种子数作为开始,如果没有提供种子数那么就从当前运行时间作为种子数。
当前系统运行时间。
2.SecureRandom 属于强随机数,一般不单独采用时间作为随机数种子,还会采用临时文件夹中大小,某个线程从休眠到被唤醒所耗的时间等等一系列无法重现的值作为随机数种子。SecureRandom 一般用于安全、加密 API,以及 UUID 的生成。(不在考虑范围)
3.上证指数、深证指数产生方式
证指数、深证指数会根据当日的总交易金额量,交易笔数等通过一系列算法产生。
受限于交易的人数和金额有很大随机性和不可控制性。上证指数、深证指数也常被作为公平的随机数出现。
根据以上原理 设计了一种公平公正的按照购买者随机位置确定幸运者的抽奖方案。欢迎拍砖。
设计方案:
购买者100个人,0-99共100个位置。 不根据购买的先后顺序决定购买者的位置,而是随着每个购买者的加入随机分配他们的位置。
第一步:随机数实现
1.构造一个可容纳100个数值的数值集合A。
2.采用系统时间毫秒数值,通过Math.random(),不停的产生0--100之间的随机数,加到数值集合A中,如果发现有重复的数字就忽略,继续产生并添加。直到集合A被填满。
3.这时候A集合内的100个位置上的数字均为随机生成。且均匀分布。 数字范围 1--100
4.根据当前的购买者数量为购买者分配随机位置,(有几个就用几个,没有使用的随机数直接舍弃)
5.每个购买者加入的时候,都会重复 1、2、3、4 四个步骤保证每次都随机生成位置。直到100个购买者全部购买完毕,最后一次100个随机数也被使用完毕。
第二步:通过邮件、图片截图、短信等方式,向所有购买者公示0-99个位置上的随机数字 。
确定在某年某月某日 如:2013-10-12 公布
第三步:在“第二天”采用上证指数或者深证指数的小数点后两位,确定前一天公布的幸运位置。
例如2013-10-13日 上证收盘1256.35 就取 35 。
确定0-99个位置上对应数字35的那个位置为幸运号码。
关键点1:0-99位置上的数字是伪随机实现,但是不可预测。
关键点2:必须在“第一天” 位置公示之后,用“第二天”的上证指数来决定第一天公布的“幸运位置”。
关键在于时间差一天。
公平,公正,透明且无法作弊的原因:第一天 在已经公示了各个位置的情况下。采用第二天的随机数来指定第一天幸运位置
两组互相独立的随机数字,存在“未来数字”决定“过去现实位置”从而保证无法进行作弊。
问题一:如果伪随机数字可以预测,能否改变最终方案的公平性?
问题二:如果上证指数可以预测,能否改变最终方案的公平性?
问题三:如果伪随机数字可以被预测,上证指数也可以预测,能否改变最终方案的公平性?
问题四:除了用黑客手段,同时改变上证指数,网站公示图片,所有已经发出的短信,邮件这种极端的方法,还有什么办法可以影响公平结果?
问题五:问题四所用的极端方法,实现的概率是多少,有没有可能?