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 }