用Java Random获取到2021(趣味向)

简介: 只需要0xffff、1、0、10这4个数字,就能通过Java Random获取到2021,也许没什么实际用处,但十分有趣

Random这个东西非常好玩,Random的seed使用的就是AtomicLong类型,AtomicLong的value使用的volatile关键字可以避免读取出寄存器中的脏数据,而数值更新时使用的Unsafe内存操作极其高效,完美的避免了synchronized的性能负担,这在Random.next()运作时非常重要,因为如果两次使用了同样的seed,在next()得到的随机结果必然相同。

好玩的地方在于,这个seed是可以设置的,不但在construction中可以自定义seed,也可以使用setSeed(long seed)切换到新的seed,这一点是很好理解的,毕竟将System.nanoTime()和一些魔法数字混合属于伪随机,Random将seed作为只写属性,为Random的真随机留了一扇门。

如果想生成一些奇怪的数字,random是再合适不过的了,只要有合适的seed与一个合适的bound,它几乎能得到任何范围内的值,我决定将bound设为10000,检索0到0xffff间的seed。

for (int i = 0; i < 0xffff; i++) {
   
    Random r = new Random(i);
    if (r.nextInt(10000) == 2021) {
   
        System.out.println(i);
    }
}
3318
14001
24132
25562
30727
46376
50878

由于范围小几乎秒出结果,这些seed都是合适的

使用不同的bound也可以得出合适的结果

for (int i = 0; i < 0xffff; i++) {
   
    Random r = new Random(1);
    if (r.nextInt(10000 + i) == 2021) {
   
        System.out.println(i);
    }
}
6286
22572
38187

以下两种方式都能得到2021

new Random(3318).nextInt(10000)
new Random(1).nextInt(16286)

不断的进行nextInt()可以得到更多数字,将seed置为0,round设在10000,经过不断nextInt()依然可以得到2021

Random r = new Random(1);
for (int i = 0; i < 15683; i++) {
   
    r.nextInt();
}
System.out.println(r.nextInt(10000));
//2021

注意: round不影响下一次随机时的seed。seed每次自动更新,都是由旧seed进行以下计算得出的

((oldseed * 0x5DEECE66DL + 0xBL) & 0xffffffffffff

现有的这些数字,都是一些杂乱数据,不美观,我扩大范围,将seed设为0xffff,由于0xffff这个范围对于2021还是太大,难以检索出有趣的数字,我右移一位,使round为实际值为0x7fff,进行海量的检索,找到了两个看上去很好玩的数字

42174
47124

看到这个突然眼前一亮,这两个数字互相倒置,循环数量达到这两个数字都会得到2021,我直接检索这种规则的数字,看看除了2021还有哪些

final int seed = 0xffff;
final int round = seed >> 1;
for (int i = 0; i < seed; i++) {
    
    Random foo = new Random(seed);
    Random bar = new Random(seed);
    int reverse = 0;
    int temp = i;
    while (temp != 0) {
    
        reverse = reverse * 10 + (temp % 10);
        temp /= 10;
    }
    //i % 10 == 0用来排除个位数的情况
    if (i == reverse || i % 10 == 0) {
    
        continue;
    }
    IntStream.range(0, i).forEach(e -> foo.nextInt());
    IntStream.range(0, reverse).forEach(e -> bar.nextInt());
    int res = foo.nextInt(round);
    if (res == bar.nextInt(round)) {
    
        System.out.println(res);
    }
}
}
18482
18482
2021
2021
16307

满足这种规则的数字确实稀少,除了2021还有18482,16307这两个数字,但2021恰好夹在中间好尴尬,不过这个16307为什么没有重复两次呢?我的规则是他的循环的次数,倒置过来也必须得到他呀,不应该有两次么,得看看他的循环次数,将打印行改为

System.out.println(res + ":" + i + ":" + reverse);

得到

18482:17092:29071
18482:29071:17092
2021:42174:47124
2021:47124:42174
16307:53609:90635

原来是因为将他的数字倒转,就超过了我设置的循环上限0xffff,他只能打印循环53609次的16307,无法进行90635的第二次打印,我加上reverse > n的判断排除它即可,现在就只需要倒排序,将2021放在首位,即可得到2021了

最终代码如下:

final int seed = 0xffff;
final int round = seed >> 1;
for (int i = seed; i > 0; i--) {
   
    Random foo = new Random(seed);
    Random bar = new Random(seed);
    int reverse = 0;
    int temp = i;
    while(temp != 0) {
   
        reverse = reverse * 10 + (temp % 10);
        temp /= 10;
    }
    if (i == reverse || i % 10 == 0 || reverse > seed) {
   
        continue;
    }
    IntStream.range(0, i).forEach(e -> foo.nextInt());
    IntStream.range(0, reverse).forEach(e -> bar.nextInt());
    int res = foo.nextInt(round);
    if (res == bar.nextInt(round)) {
   
        System.out.println(res);
        break;
    }
}

我同样贴在了 https://gist.github.com/lyrieek/61b435d26c10aba82b17d65f180199ab

目录
相关文章
|
2天前
|
Java
Java——Math、BigInteger和Random类
Java——Math、BigInteger和Random类
18 0
|
2天前
|
存储 Java
35、Java 中的 Math 类、Random 随机数、UUID、格式化字符串或数字、字符串和数字的相互转换、高精度计算、BigDecimal、计算机中的浮点数都是近似值
35、Java 中的 Math 类、Random 随机数、UUID、格式化字符串或数字、字符串和数字的相互转换、高精度计算、BigDecimal、计算机中的浮点数都是近似值
50 0
|
5月前
|
Java
【零基础学Java】—Random的基本概述和使用(十二)
【零基础学Java】—Random的基本概述和使用(十二)
|
6月前
|
安全 Java 数据安全/隐私保护
java random随机数的用法
java random随机数的用法
|
8月前
|
Java API
Java常用API(二)Random,System与Math
Java常用API(二)Random,System与Math
43 0
|
9月前
|
存储 安全 Java
Java类库StrringBuffer类、Math、SimpleDateFormat、Random随机数、大数字处理类和UUID 无重复数据(附带面试题)
1.StrringBuffer类 CharConsequnse接口,2.Math数学计算,3.Date日期处理类与SimpleDateFormat、4.Random随机数、5.大数字处理类、6.UUID 无重复数据
77 0
|
9月前
|
Java
Java Random(随机函数)
Java Random(随机函数)
42 0
|
10月前
Java-Random与random
Java-Random与random
|
10月前
|
机器学习/深度学习 传感器 算法
【JavaSE专栏42】Java常用类Random解析,伪随机数的生成
【JavaSE专栏42】Java常用类Random解析,伪随机数的生成
129 0
|
11月前
|
Java