Exemplo n.º 1
0
        public override void SetSeed(ulong[] seed)
        {
            // Don't allow all zero values with this generator.
            if (seed == null || CleromUtil.IsArrayZero(seed))
            {
                SetStartingState();

                // Important to reset base cache
                ResetCache();
            }
            else
            if (seed.Length > 0)
            {
                if (seed.Length == 1)
                {
                    SetStartingState();
                    state0 = seed[0];
                }
                else
                {
                    state0 = seed[0];
                    state1 = seed[1];
                }

                ResetCache();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// LCG constructor.
        /// <para>It is possible to define a randMax value less than or equal to m-1, as used by
        /// Rand48Lcg. Setting m to 0 negates the modulus.</para>
        /// </summary>
        /// <param name="randMax">Maximum value returned by Next()</param>
        /// <param name="a">Multiplier</param>
        /// <param name="c">Increment</param>
        /// <param name="m">Modulus</param>
        public LcgRng(ulong randMax, ulong a, ulong c, ulong m)
            : base(randMax)
        {
            if (m != 0 && m <= randMax)
            {
                throw new ArgumentException("randMax", "The RandMax value " + randMax +
                                            "is invalid (not possible with modulus " + m + ").");
            }

            mult = a;
            inc  = c;
            mod  = m;

            // Determine a bit mask to use instead of modulus, if possible.
            // This yields as big performance improvement as the C# "%" operator
            // does not appear optimized where the maximum result is a power of 2 value.

            // Default where modulus is 0,
            // which implicitly means 2^64.
            modMask = UInt64.MaxValue;

            if (mod != 0)
            {
                modMask = mod - 1;

                // Number of bits needed by modulus
                int mbits = CleromUtil.BitSize(modMask);

                // If not equal, we can't use a mask.
                if (modMask != UInt64.MaxValue >> (64 - mbits))
                {
                    modMask = 0;
                }
            }
        }
Exemplo n.º 3
0
        public override void SetSeed(ulong[] seed)
        {
            // Don't allow all zero values with this generator.
            if (seed == null || CleromUtil.IsArrayZero(seed))
            {
                SetStartingState();

                // Important to reset base cache
                ResetCache();
            }
            else
            if (seed.Length > 0)
            {
                if (seed.Length < StateSize)
                {
                    SetStartingState();
                    Buffer.BlockCopy(seed, 0, state, 0, seed.Length * sizeof(ulong));
                }
                else
                {
                    Buffer.BlockCopy(seed, 0, state, 0, StateSize * sizeof(ulong));
                }

                stateIdx = 0;
                ResetCache();
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Generates a new random seed of SeedLength values for use with seeding the generator,
        /// but does not modify the state of the generator itself. It is called by Randomize().
        /// <para>The seed is generated by the underlying OS via the RNGCryptoServiceProvider
        /// class. It may be overridden to generate seeds according to custom requirements.</para>
        /// </summary>
        public virtual TInteg[] GenerateSeed()
        {
            TInteg[] rslt  = null;
            byte[]   bytes = new byte[SeedLength * TypeSize];

            if (bytes.Length > 0)
            {
                RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
                crypto.GetBytes(bytes);
                rslt = CleromUtil.ConvertBytesToArray <TInteg>(bytes);
            }

            return(rslt);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Sets the generator to a new state, defined by a single 64-bit integer seed value.
 /// <para>This overloaded variant of SetSeed() provides a convenient means to seed
 /// any generator with a single integer value.</para>
 /// <para>Its behavior is as follows:</para>
 /// <para>If SeedLength is 1, the seed value will be cast to the corresponding TInteg
 /// type, copied to an array of length 1, and passed directly to SetSeed(TInteg[]).</para>
 /// <para>If SeedLength is larger than 1, the integer seed will be "expanded" to an array
 /// of SeedLength values, which will then be passed to SetSeed(TInteg[]).</para>
 /// <para>The number of possible seed values using this method may, therefore, be
 /// significantly less than that supported by the SetSeed(TInteg[]) array variant.</para>
 /// <para>Seeding with this method or, indeed, with any single integer value, should
 /// not be considered suitable for cryptographic use.</para>
 /// <para>Furthermore, seed expansions are to be considered implementation dependent,
 /// in the sense that the implementation may potentially change with some future update
 /// to the library.</para>
 /// <para>Currently, expansions are performed using the SPLITMIX64 generator which,
 /// itself, has a 64-bit seed type. If you require future-proof repeatability,
 /// override this method with your own.</para>
 /// </summary>
 /// <param name="seed">Integer seed value</param>
 public virtual void SetSeed(ulong seed)
 {
     if (SeedLength == 1)
     {
         var arr = new TInteg[1];
         arr[0] = (TInteg)(dynamic)seed;
         SetSeed(arr);
     }
     else
     {
         SplitMix64 temp = new SplitMix64();
         temp.SetSeed(seed);
         byte[] bs = temp.GetBytes(TypeSize * SeedLength);
         SetSeed(CleromUtil.ConvertBytesToArray <TInteg>(bs));
     }
 }
Exemplo n.º 6
0
        /// <summary>
        /// Subclasses must supply 'randMax', the maximum possible value returned by the
        /// implementation of the Next() method.
        /// </summary>
        /// <param name="randMax">Maximum value returned by Next()</param>
        public Rng(ulong randMax)
        {
            if (randMax == 0)
            {
                throw new ArgumentException("randMax", "RandMax cannot be zero!");
            }

            // Set read-only values
            nativeMax = randMax;
            native64  = (randMax == UInt64.MaxValue);
            native32  = (randMax == UInt32.MaxValue);

            // Get number of bits to use from Next().
            // A RandMax of 2^31-1 gives us 31.
            shiftBits = CleromUtil.BitSize(randMax);
            shiftMax  = UInt64.MaxValue >> (64 - shiftBits);

            if (randMax != shiftMax)
            {
                --shiftBits;
                shiftMax >>= 1;
            }

            // Initialize cache values
            ResetCache();

            // Useful for confirming properties when debugging

            /*
             * Console.WriteLine();
             * Console.WriteLine("NAME       : " + AlgorithmName);
             * Console.WriteLine("RandMax    : " + randMax);
             * Console.WriteLine("RandMax    : 0x" + randMax.ToString("X16"));
             * Console.WriteLine("Native32   : " + native32);
             * Console.WriteLine("Native64   : " + native64);
             * Console.WriteLine("BitShift  : " + shiftBits);
             * Console.WriteLine();
             */
        }