View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.rng.core.source64;
18  
19  import org.apache.commons.rng.core.RandomAssert;
20  import org.junit.jupiter.api.Test;
21  
22  class XoRoShiRo128PlusTest {
23      /** The size of the array SEED. */
24      private static final int SEED_SIZE = 2;
25  
26      /*
27       * Data from running the executable compiled from the author's C code:
28       *   http://xoshiro.di.unimi.it/xoroshiro128plus.c
29       */
30  
31      private static final long[] SEED = {
32          0x012de1babb3c4104L, 0xa5a818b8fc5aa503L,
33      };
34  
35      private static final long[] EXPECTED_SEQUENCE = {
36          0xa6d5fa73b796e607L, 0xd419031a381fea2eL, 0x28938b88b4972f52L, 0x032793a0d51c1a27L,
37          0x50001cd69cc5b006L, 0x44bbf571167cb7f0L, 0x172f6a2f093b2befL, 0xe642c831f1e4f7bfL,
38          0xcec4e4b5d448032aL, 0xc0164992807cbd59L, 0xb96ff06c68515410L, 0x5288e0312a0aae72L,
39          0x79a891c387d3be2eL, 0x6c52f6f710db553bL, 0x2ce6f6b1946862b3L, 0x87eb1e1b24b47f11L,
40          0x9f7c3511c5f23bcfL, 0x3254897533dcd1abL, 0x89d56ad217fbd1adL, 0x70f6b269f815f6e6L,
41          0xe8ee60efadfdb8c4L, 0x09286db69fdd232bL, 0xf440882651fc19e8L, 0x6356fea018cc26cdL,
42          0xf692282b43fcb0c2L, 0xef3f084929119babL, 0x355efbf5bedeb114L, 0x6cf5089c2acc96ddL,
43          0x819c19e480f0bfd1L, 0x414d12ff4082e261L, 0xc9a33a52545dd374L, 0x4675247e6fe89b3cL,
44          0x069f2e55cea155baL, 0x1e8d1dcf349746b8L, 0xdf32e487bdd74523L, 0xa544710cae2ad7cdL,
45          0xf5ac505e74fe049dL, 0xf039e289da4cdf7eL, 0x0a6fbebe9122529cL, 0x880c51e0915031a3L,
46      };
47  
48      private static final long[] EXPECTED_SEQUENCE_AFTER_JUMP = {
49          0xb715ad9cb572030eL, 0x10634f817a8f69b1L, 0xe871b367a8f9c567L, 0x3096f4ceb23198cdL,
50          0xf5b09c8734d26da9L, 0x58ba83f779a2549cL, 0xb6c54c8ea9fc672bL, 0x87bb9766ff20834dL,
51          0x2686d4a93b9bb8a7L, 0xababdb798931fbfbL, 0xc9ce83b35259eb39L, 0xe2314c9488d44131L,
52          0x5841497fb6fe3a62L, 0x00ecd78f2eba1e81L, 0x4aed6d184b3ada35L, 0xb33681cb7e39c9d0L,
53          0x911498e07cb3d3ceL, 0xea92a7dfb98aa971L, 0x5db49f2f3f22321cL, 0x4982bae495d875f4L,
54          0xa436167ccfb3a982L, 0x646b0fe680176bb2L, 0x8312610f7e93a41fL, 0xa67a4d13d12cb264L,
55          0xf22330689f003fa8L, 0xfa0d7f3712db37beL, 0x409b34496c4a847cL, 0x9ac1b246a47e2a17L,
56          0x6006078c0c743c74L, 0x457ef921811029ecL, 0xd6d9f58851583575L, 0xabbdd4ac3c49239bL,
57          0xc07444095ef29743L, 0x75a2eb7c74f95d6eL, 0xd0ead6726a91ada9L, 0x9749e96908129418L,
58          0x83ae5b12eb343545L, 0x10828fde12decab5L, 0x6952d51f130505b7L, 0x9b6bd81fbe064f54L,
59      };
60  
61      private static final long[] EXPECTED_SEQUENCE_AFTER_LONG_JUMP = {
62          0xf569a89f3ee6fa3dL, 0x3c61867cbcc208a8L, 0x95a83b710aa1a57fL, 0xed5c658383559407L,
63          0xbb70b6959a82f3b0L, 0x31eab244213fe7beL, 0xe14bb9d50b6b026fL, 0x80716d04b81d5aaaL,
64          0x5451ede574559e11L, 0x1aa1d87fdfb78d52L, 0x38e4a2c33f97870fL, 0xf88a98d8376a95b5L,
65          0x5b88ec173f131549L, 0x642af091aab9643aL, 0x92edb9171a703919L, 0xf65bd2ac6b1efd62L,
66          0xe10b1da6e5b2efafL, 0xf2abec22c6c4170dL, 0xa5b853b7dee402c1L, 0xe45d2ec5e488cac3L,
67          0x64f126a2065224d6L, 0x5e4f64edde60e852L, 0xc8dc8819696ef333L, 0x1a9acfaa4a10f22bL,
68          0xd75be7f8487d1c52L, 0x7759ec0ea4b8e698L, 0xc36b934a78c463e2L, 0x2c7257c4228f7948L,
69          0x0651b8c869027343L, 0xe66b122fec5ca8a1L, 0xe3f8ad0bcf74642dL, 0x08f46e481eec937aL,
70          0xccd1c4419af68187L, 0x93396af913995faeL, 0x95ee2988b39a3534L, 0x7da239ae0dd79948L,
71          0xa0fdcf90f2e3ab22L, 0xb2e20b2ce7a83f7aL, 0xd1346542947f8b0dL, 0xa95894552bbb2460L,
72      };
73  
74      @Test
75      void testReferenceCode() {
76          RandomAssert.assertEquals(EXPECTED_SEQUENCE, new XoRoShiRo128Plus(SEED));
77      }
78  
79      @Test
80      void testConstructorWithZeroSeedIsNonFunctional() {
81          RandomAssert.assertNextIntZeroOutput(new XoRoShiRo128Plus(new long[SEED_SIZE]), 2 * SEED_SIZE);
82      }
83  
84      @Test
85      void testConstructorWithSingleBitSeedIsFunctional() {
86          RandomAssert.assertLongArrayConstructorWithSingleBitSeedIsFunctional(XoRoShiRo128Plus.class, SEED_SIZE);
87      }
88  
89      @Test
90      void testConstructorWithoutFullLengthSeed() {
91          // Hit the case when the input seed is self-seeded when not full length
92          RandomAssert.assertNextLongNonZeroOutput(new XoRoShiRo128Plus(new long[] {SEED[0]}),
93                  SEED_SIZE, SEED_SIZE);
94      }
95  
96      @Test
97      void testElementConstructor() {
98          final XoRoShiRo128Plus rng1 = new XoRoShiRo128Plus(SEED);
99          final XoRoShiRo128Plus rng2 = new XoRoShiRo128Plus(SEED[0], SEED[1]);
100         RandomAssert.assertNextLongEquals(SEED.length * 2, rng1, rng2);
101     }
102 
103     @Test
104     void testJump() {
105         RandomAssert.assertJumpEquals(EXPECTED_SEQUENCE, EXPECTED_SEQUENCE_AFTER_JUMP, new XoRoShiRo128Plus(SEED));
106     }
107 
108     @Test
109     void testLongJump() {
110         RandomAssert.assertLongJumpEquals(EXPECTED_SEQUENCE, EXPECTED_SEQUENCE_AFTER_LONG_JUMP, new XoRoShiRo128Plus(SEED));
111     }
112 }