java固定种子随机数预测

听说java随机数是伪随机就是通过一个种子进行运算得出,既然这样那么应该可以通过随机数再次得到种子,通过种子再次得到接下来的所有随机数。
首先看下随机数的生成,随机数生成一个是带种子一个是不带种子,不带种子的默认用seedUniquifier() ^ System.nanoTime() 作为种子,seedUniquifier()是一个线性值可预测
唯一预测起来比较麻烦的是System.nanoTime() =23429979025971 类似于这样的一个电脑纳秒值,再加上cpu的运算几乎算是随机的了,如果是带种子的话那么随机数就可以预测了。
之前在网上找随机数逆向算法没找到所以就自己研究了下,现在写成文章以免日后自己忘记了可以通过文章快速上手,其次也给各位一个参考,代码未格式化和整理的第一手代码,如果整理了我怕我以后上手麻烦。什么线性同余算法什么梅森算法完全看不懂,就是按照一个随机数然后逆向算出种子然后在随机出接下来的随机数。
/**/
for (long i = 23429979025971L; i <= 23429979025971L; i++) {
Random random=new Random(i,i);
for (int j = 1; j <= 5; j++) {



Double d=random.nextDouble();
//if((d)==0.9943732600499389){

System.out.println(i+”->”+j+”->”+System.currentTimeMillis()+”->”+d);

// return;
//}
}

Random.seedUniquifier=Random.seedUniquifier1;

//System.out.println(i+”->”+System.currentTimeMillis()+”->”+d);


}
一个固定种子生成
public Random(long seed,long seed1) {

    seed=seedUniquifier() ^ seed1;



    //System.out.println(seed+"-->"+seedUniquifier);

    if (getClass() == Random.class)
        this.seed = new AtomicLong(initialScramble(seed));
    else {
        // subclass might have overriden setSeed
        this.seed = new AtomicLong();
        setSeed(seed);
    }
}


public double nextDouble() {

    long  l=next(26); //56434140
    long l2=l<< 27;//7574462052433920


    long l1=next(27);//100224743

    return (((long)(l2)) + l1) / (double)(1L << 53);  // (((long)(next(26)) << 27) + next(27)) / (double)(1L << 53);
    //     7574462052433920  + 100224743   /9007199254740992
}


public int next(int bits) {
    long oldseed, nextseed;
    AtomicLong seed = this.seed;
    do {
        oldseed = seed.get();
        //236701939854949=(134332725245826*25214903917+11) & 281474976710655; >>>22= 56434140

        //210186521427724=(236701939854949*25214903917+11) & 281474976710655; >>>21= 100224743
        nextseed = (oldseed * multiplier + addend) & mask;
    } while (!seed.compareAndSet(oldseed, nextseed));

    int i=(int)(nextseed >>> (48 - bits));//56434140 100224743  
    return i;  
}

—————————————————————-上面是一个固定种子生成随机数的过程——————————————————————-

—————————————————————-下面是一个固定种子随机数逆向运算的过程——————————————————————-

/**
* 分解随机数
* @param args
*/
public static long[] 分解随机数(double args) {

    long l1=(long)(args*9007199254740992d);//7574462152658663/9007199254740992=0.8409342281033475

    long l2=(long)l1>>>27;

    long l3=l1-(l2<<27);

    long []larr={l2,l3};

    System.out.println(l1+"="+l2+"-"+l3);

    return  larr;
}



public static long 分析种子(long l2,long l3){

    long l4=l2<<22;

    for (int i = 0; i < (1<<22)-1; i++) {

// long l2,l3;

                if((((l2=l4+i)*25214903917L+11) & 281474976710655L)>>>21==l3){

                    //long l1=(((236701939138560L+i)*25214903917L+11) & 281474976710655L);

                    System.out.println(l2+"--->"+(l3>>>21));
                    return  l2;
                    // //210186521427724=(236701939854949*25214903917+11) & 281474976710655; >>>21= 100224743

                }



            }
    return  l2;
}



public static void 预测随机数(long seed){


    Random random=new Random(259366953981575L);

    random.seed=new AtomicLong(seed);

    random.next(1);

    int i1=0;

    for (int i = 0; i < 1000; i++) {

        Double d=random.nextDouble();

        double flag=d;
        flag -= Math.floor(flag);
        flag *= 100;



        System.out.println(d+"--->"+(flag<65));

/* if(flag<65){
i1++;
}else{
if(i1>0){
System.out.println(i1);
}
i1=0;
}*/

    }





}

一共3个类下载地址 没分的找我 单独发
test8.java
test9.java
Random.java

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值