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 XoShiRo256PlusTest {
23      /** The size of the array SEED. */
24      private static final int SEED_SIZE = 4;
25  
26      /*
27       * Data from running the executable compiled from the author's C code:
28       *   http://xoshiro.di.unimi.it/xoshiro256plus.c
29       */
30  
31      private static final long[] SEED = {
32          0x012de1babb3c4104L, 0xa5a818b8fc5aa503L, 0xb124ea2b701f4993L, 0x18e0374933d8c782L,
33      };
34  
35      private static final long[] EXPECTED_SEQUENCE = {
36          0x1a0e1903ef150886L, 0x08b605f47abc5d75L, 0xd82176096ac9be31L, 0x8fbf2af9b4fa5405L,
37          0x9ab074b448171964L, 0xfd68cc83ab4360aaL, 0xf431f7c0c8dc6f2bL, 0xc04430be08212638L,
38          0xc1ad670648f1da03L, 0x3eb70d38796ba24aL, 0x0e474d0598251ed2L, 0xf9b6b3b56482566bL,
39          0x3d11e529ae07a7c8L, 0x3b195f84f4db17e7L, 0x09d62e817b8223e2L, 0x89dc4db9cd625509L,
40          0x52e04793fe977846L, 0xc052428d6d7d17cdL, 0x6fd6f8da306b10efL, 0x64a7996ba5cc80aaL,
41          0x03abf59b95a1ef20L, 0xc5a82fc3cfb50234L, 0x0d401229eabb2d39L, 0xb537b249f70bd18aL,
42          0x1af1b703753fcf4dL, 0xb84648c1945d9ccbL, 0x1d321bea673e1f66L, 0x93d4445b268f305fL,
43          0xc046cfa36d89a312L, 0x8cc2d55bbf778790L, 0x1d668b0a3d329cc7L, 0x81b6d533dfcf82deL,
44          0x9ca1c49a18537b16L, 0x68e55c4054e0cb72L, 0x06ed1956cb69afc6L, 0x4871e696449da910L,
45          0xcfbd7a145066d46eL, 0x10131cb15004b62dL, 0x489c91a322bca3b6L, 0x8ec95fa9bef73e66L,
46      };
47  
48      private static final long[] EXPECTED_SEQUENCE_AFTER_JUMP = {
49          0x894cd8014fa285abL, 0x9737ec9aba91e4b6L, 0xf53b956d74db413aL, 0x6fb0350e20edef6bL,
50          0x1babe425f938088fL, 0x04f33708a2103773L, 0x03a3f59f511629dfL, 0x9d7323fd9cc8f542L,
51          0x8df0f8083323117bL, 0x9097a2cc69730c34L, 0x54e01393f7e1c5f6L, 0x14971cb42dce9e33L,
52          0x6ee4f7da32d287feL, 0x36124f300901b735L, 0x71726514f0341ccaL, 0xbdd6ff5845590a93L,
53          0x75982d4223903b23L, 0x75e88dbec205937cL, 0x82fa1ef5ed2d3ff5L, 0x49983b880a0758b8L,
54          0x8d3d74acd90595ccL, 0x1176ea450c32b01fL, 0xfddac8dca767aee0L, 0xbd8226c3f021dcfdL,
55          0xf95c1aead608a5f9L, 0xc7bd37c9a128d4f2L, 0x8abc94eb440371ceL, 0x4f86410df47f6928L,
56          0xd2d3479afe5730feL, 0xa7e02f6550aa6668L, 0x5f8b8630e9f5814eL, 0xe8c605350467cdccL,
57          0xecc91d6be68b5d11L, 0xbe9382f9d9e9e205L, 0xb512c7b80ca731f1L, 0x5125f56b47a89007L,
58          0x6d98bfd64342222bL, 0x7244f91ff7efc522L, 0xbcf26439fef5555fL, 0xce657c86d81455ceL,
59      };
60  
61      private static final long[] EXPECTED_SEQUENCE_AFTER_LONG_JUMP = {
62          0x1cf7608ee3f54c71L, 0xd9ec5faa2133c458L, 0xee0c3c44ac9a4571L, 0x8e6dd93270d03b83L,
63          0x44268688ca3c44b2L, 0x07aefb00d1cd925fL, 0x3733c3fe9831692dL, 0x2d2c5df21bfd31b2L,
64          0x1253a79c879276c2L, 0xf862b65e4bcb6bcfL, 0xf6dbb01651a1b8b5L, 0x68476e3a6b9bf559L,
65          0xb135e7151bafae3eL, 0x6e905be176bb02bfL, 0xa5ee1972ed7e090cL, 0x2cad1fadf7be52d6L,
66          0x1a34866325f9ae69L, 0xec4f680ff02209c1L, 0x4f01371b2db5a1c3L, 0x566fb6f85561d4d0L,
67          0x75fec1eb21866b41L, 0xfaff7b899909d846L, 0xe9e1bc7229c28446L, 0x63389a9af17857c5L,
68          0x07233b15e9f42541L, 0x46e262e3ba5c337cL, 0xfac8e73ae594bbd9L, 0x990562a1cbaf25d8L,
69          0xd99269c3ac01c7a0L, 0x20c249266bba8447L, 0x947bf8bc4e0e8deaL, 0xbd69e3c43fa8582aL,
70          0x7fb6e0e0d918bba6L, 0x95633e090da85696L, 0x1529c0b55ede291bL, 0x9034b247848dc3beL,
71          0x6422cc4a32efeb31L, 0x6334a19977a2fca6L, 0x016a2c7af8cf0eefL, 0x49dab6a0dc871a1cL,
72      };
73  
74      @Test
75      void testReferenceCode() {
76          RandomAssert.assertEquals(EXPECTED_SEQUENCE, new XoShiRo256Plus(SEED));
77      }
78  
79      @Test
80      void testConstructorWithZeroSeedIsNonFunctional() {
81          RandomAssert.assertNextIntZeroOutput(new XoShiRo256Plus(new long[SEED_SIZE]), 2 * SEED_SIZE);
82      }
83  
84      @Test
85      void testConstructorWithSingleBitSeedIsFunctional() {
86          RandomAssert.assertLongArrayConstructorWithSingleBitSeedIsFunctional(XoShiRo256Plus.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 XoShiRo256Plus(new long[] {SEED[0]}),
93                  SEED_SIZE, SEED_SIZE);
94      }
95  
96      @Test
97      void testElementConstructor() {
98          final XoShiRo256Plus rng1 = new XoShiRo256Plus(SEED);
99          final XoShiRo256Plus rng2 = new XoShiRo256Plus(SEED[0], SEED[1], SEED[2], SEED[3]);
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 XoShiRo256Plus(SEED));
106     }
107 
108     @Test
109     void testLongJump() {
110         RandomAssert.assertLongJumpEquals(EXPECTED_SEQUENCE, EXPECTED_SEQUENCE_AFTER_LONG_JUMP, new XoShiRo256Plus(SEED));
111     }
112 }