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.source32;
18  
19  import org.apache.commons.rng.core.util.NumberFactory;
20  
21  /**
22   * Implement Bob Jenkins's small fast (JSF) 32-bit generator.
23   *
24   * <p>The state size is 128-bits; the shortest period is expected to be about 2<sup>94</sup>
25   * and it expected that about one seed will run into another seed within 2<sup>64</sup> values.</p>
26   *
27   * @see <a href="https://burtleburtle.net/bob/rand/smallprng.html">A small noncryptographic PRNG</a>
28   * @since 1.3
29   */
30  public class JenkinsSmallFast32 extends IntProvider {
31      /** State a. */
32      private int a;
33      /** State b. */
34      private int b;
35      /** State c. */
36      private int c;
37      /** Statd d. */
38      private int d;
39  
40      /**
41       * Creates an instance with the given seed.
42       *
43       * @param seed Initial seed.
44       */
45      public JenkinsSmallFast32(Integer seed) {
46          setSeedInternal(seed);
47      }
48  
49      /**
50       * Seeds the RNG.
51       *
52       * @param seed Seed.
53       */
54      private void setSeedInternal(int seed) {
55          a = 0xf1ea5eed;
56          b = c = d = seed;
57          for (int i = 0; i < 20; i++) {
58              next();
59          }
60      }
61  
62      /** {@inheritDoc} */
63      @Override
64      public final int next() {
65          final int e = a - Integer.rotateLeft(b, 27);
66          a = b ^ Integer.rotateLeft(c, 17);
67          b = c + d;
68          c = d + e;
69          d = e + a;
70          return d;
71      }
72  
73      /** {@inheritDoc} */
74      @Override
75      protected byte[] getStateInternal() {
76          return composeStateInternal(NumberFactory.makeByteArray(new int[] {a, b, c, d}),
77                                      super.getStateInternal());
78      }
79  
80      /** {@inheritDoc} */
81      @Override
82      protected void setStateInternal(byte[] s) {
83          final byte[][] parts = splitStateInternal(s, 4 * 4);
84  
85          final int[] tmp = NumberFactory.makeIntArray(parts[0]);
86          a = tmp[0];
87          b = tmp[1];
88          c = tmp[2];
89          d = tmp[3];
90  
91          super.setStateInternal(parts[1]);
92      }
93  }