package com.yagou.yggx.provider.ygst.task;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class ReaperMd5 {
public static void main(String[] args) throws NoSuchAlgorithmException {
//
// 为了确保游戏的公平性,我们采用HASH值方案以防止游戏过程中作弊,
// 即在游戏的过程中,从一开始就已经产生了随机的百分比值,
// 在游戏结束后,通过计算游戏参与方的百分比值区间,转化为相对应的筹码,从进而确定中奖者。
/**
* java中 随机数的 产生的三种方式
*/
// 一.在j2se里我们可以使用Math.random()方法来产生一个随机数,
// 这个产生的随机数是0-1之间的一个double,我们可以把他乘以一定的数,
// 比如说乘以100,他就是个100以内的随机,这个在j2me中没有。
double random001 = Math.random();
System.out.println(random001);
// 二.在java.util这个包里面提供了一个Random的类,我们可以新建一个Random的对象来产生随机数,
// 他可以产生随机整数、随机float、随机double,随机long,这个也是我们在j2me的程序里经常用的一个取随机数的方法。
// 不带种子:
// 此种方式将会返回随机的数字,每次运行结果不一样
System.out.println("不带种子: ");
System.out.println("此种方式将会返回随机的数字,每次运行结果不一样 ");
System.out.println("");
java.util.Random r=new java.util.Random();
for(int i=0;i<1;i++){
System.out.println(r.nextInt());
}
// 带种子:
// 此种方式,无论程序运行多少次,返回结果都是一样的
System.out.println("带种子:");
System.out.println("此种方式,无论程序运行多少次,返回结果都是一样的 ");
System.out.println("");
java.util.Random r1=new java.util.Random(10);
for(int i=0;i<1;i++){
System.out.println(r1.nextInt());
}
// 三.在我们的System类中有一个currentTimeMillis()方法,这个方法返回一个从1970年1月1号0点0分0秒到目前的一个毫秒数,返回类型是long,我们可以拿他作为一个随机数,我们可以拿他对一些数取模,就可以把他限制在一个范围之内啦
long currentTime = System.currentTimeMillis();
System.out.println(currentTime%100);
//
// 关于hash值:
//
// 我们采用MD5的不可逆加密算法,在每轮游戏开始的时候,都会生成本轮的hash的值,以便玩家事后验证。
// 由于MD5具有极大的离散性, 改动任何一位数字将导致hash的不同,所以利用这个原理,我们可以确定每轮游戏的公平性。
String str = "chenzhongqiang";
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算md5函数
md.update(str.getBytes());
// digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
// BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
String bint = new BigInteger(1, md.digest()).toString(16);
System.out.println("MD5:"+bint);
//
// 我们的MD5加密格式是MD5=Random(随机码):Key(秘钥)
// 如何验证hash值: 例如,某轮游戏的hash值是A0EC3F6BC80AB7B06FC6178B41E176FE
// 当本轮游戏开奖后,网站将公布Random(随机码12.3451234512340%)和Key(秘钥RGSRDLMVLJ)。
// 您可以根据Random(随机码)和Key(秘钥), 在第三方网站(例如www.xmd5.org/Encrypt_cn.htm或者自行百度“md5加密”)进行加密验证。
// 对“12.3451234512340%:RGSRDLMVLJ” 加密后的结果就是网站提前公布的hash值A0EC3F6BC80AB7B06FC6178B41E176FE
// 常规加密md5($pass) 32位小写
String pass = "12.3451234512340%:RGSRDLMVLJ";
String hash = MD5Util.MD5(pass);
System.out.println(pass+" 的hash值为: "+hash);
random001 = 0.123451234512340;
String key = "RGSRDLMVLJ";
BigDecimal random = BigDecimal.valueOf(random001);
Md5ToHash(random, key);
// 总筹码值
double totalsteam = 454.25;
// Random(随机码)
// double random001 = 454.25;
BigDecimal totalsteamb = BigDecimal.valueOf(totalsteam);
caculateHitNumber(totalsteamb, random);
// 特别说明:随着个人计算机和服务器性能的不断提高,通过不断组合数字,
// 将各种可能加密出来实现针对Hash码暴力破解已经成为可能,因此,在结果显示前,
// 我们对Hash码第29-31位以*号进行代替,即使采用了暴力破解,对HASH码仍然有46656(36*36*36)种可能,无法预知结果。
//
//
reaper();
// Hash: CF6AE4CF3F813CC7971996A7F7929436
//
// Random: 76.2055990040504%
//
// Key: b6bsM87jEw
//
// WinnerTicket: 5349
// TODO Auto-generated method stub
// Hash: 3DA6F2523C045DE1A8D533E151D79249
//
// Random:96.6972266201678%
//
// Key: 1KB9GDcz1x
//
// WinnerTicket: 1616
}
/**
* 游戏开始
*/
public static void reaper(){
//Random(随机码)
BigDecimal random = getRandom();
// Key(秘钥
String key = "RGSRDLMVLJ";
// 总筹码值
double totalsteam = 454.25;
BigDecimal totalsteamb = BigDecimal.valueOf(totalsteam);
// 2、hash值计算
Md5ToHash(random, key);
// 3、计算中奖码
caculateHitNumber(totalsteamb, random);
}
/**
* 1、获取随机数
*/
public static BigDecimal getRandom(){
double random001 = Math.random();
System.out.println(random001);
BigDecimal random = BigDecimal.valueOf(random001).setScale(15, RoundingMode.FLOOR);
return random;
}
/**
* 2、hash值计算
*
*/
public static void Md5ToHash(BigDecimal random ,String key){
// 我们的MD5加密格式是MD5=Random(随机码):Key(秘钥)
// 如何验证hash值: 例如,某轮游戏的hash值是A0EC3F6BC80AB7B06FC6178B41E176FE
// 当本轮游戏开奖后,网站将公布Random(随机码12.3451234512340%)和Key(秘钥RGSRDLMVLJ)。
// 您可以根据Random(随机码)和Key(秘钥), 在第三方网站(例如www.xmd5.org/Encrypt_cn.htm或者自行百度“md5加密”)进行加密验证。
// 对“12.3451234512340%:RGSRDLMVLJ” 加密后的结果就是网站提前公布的hash值A0EC3F6BC80AB7B06FC6178B41E176FE
// 常规加密md5($pass) 32位小写
// String pass = "12.3451234512340%:RGSRDLMVLJ";
String pass = random.multiply(BigDecimal.valueOf(100)).setScale(13).toString() +"%:"+key;
String hash = MD5Util.MD5(pass);
System.out.println(pass+" 的hash值为: "+hash);
}
/**
* 3、计算中奖码
* @param totalsteam 总筹码值
* @param random001 Random(随机码
*/
public static void caculateHitNumber(BigDecimal totalsteam, BigDecimal random ){
// 如何选择中奖筹码:
// 0.01的steam值将等于1个筹码值Ticket,
// 比赛开奖的时候,系统将统计总筹码值TotalNumberOfTickets(例如总奖池是454.25, 则总筹码等于45425)。
// 中奖筹码的计算公式是: floor(TotalNumberOfTickets * Random)+1 例如:TotalNumberOfTickets=45425,random=12.3451234512340%,
// 则中奖筹码=floor(45425*12.3451234512340%)+1=5608
// 0.01的steam值将等于1个筹码值Ticket,
double steamPrecent = 0.01;
// 比赛开奖的时候,系统将统计总筹码值TotalNumberOfTickets(例如总奖池是454.25, 则总筹码等于45425)。
BigDecimal totalNumberOfTickets = totalsteam.multiply( BigDecimal.valueOf(1/steamPrecent));
// random = BigDecimal.valueOf(0.123451234512340);
// MathContext mc = new MathContext(random.scale(),RoundingMode.FLOOR);
// 中奖筹码的计算公式是: floor(TotalNumberOfTickets * Random)+1 例如:TotalNumberOfTickets=45425,random=12.3451234512340%,
BigDecimal hitNumber = totalNumberOfTickets.multiply(random).divide(BigDecimal.ONE, 0, RoundingMode.FLOOR).add(BigDecimal.ONE);
System.out.println("中奖筹码="+hitNumber);
}
}
DOTA2翻硬币网站规则java版本
最新推荐文章于 2023-05-29 22:50:01 发布