/Utilities/Helpers/RandomHelper.cs
C# | 379 lines | 216 code | 33 blank | 130 comment | 24 complexity | 9b166b6a5ea79fcc0ee4fbedd8367826 MD5 | raw file
Possible License(s): Apache-2.0
- using System;
- using System.Collections.Generic;
- using System.Security.Cryptography;
- using Delta.Utilities.Datatypes;
-
- namespace Delta.Utilities.Helpers
- {
- /// <summary>
- /// Random helper, which mostly provides methods to quickly generate random
- /// values for ints, floats, bytes, Vectors, Colors, etc. and some methods
- /// for more complex cases (strings, ids, random values with factors, etc.)
- /// </summary>
- public static class RandomHelper
- {
- #region GetNewRandomGenerator (Static)
- /// <summary>
- /// Get new random generator with help of
- /// Win32Function.GetPerformanceCounter.
- /// </summary>
- /// <returns>Random</returns>
- public static Random GetNewRandomGenerator()
- {
- lastUsedRandomGenerator = new Random((int)DateTime.Now.Ticks);
- //lastUsedRandomGenerator = new Random250Algorithm();
- return lastUsedRandomGenerator;
- }
- #endregion
-
- #region RandomInt (Static)
- /// <summary>
- /// Gets a random int between '0' and the given (exclusive) maximum.
- /// </summary>
- /// <param name="max">The max. (exclusive) Limit</param>
- /// <returns>Int</returns>
- public static int RandomInt(int max)
- {
- if (max <= 0)
- {
- return 0;
- }
-
- return lastUsedRandomGenerator.Next(max);
- }
-
- /// <summary>
- /// Gets a random int between the given minimum and (exclusive) maximum.
- /// </summary>
- /// <param name="min">Min</param>
- /// <param name="max">Max</param>
- /// <returns>Random int</returns>
- public static int RandomInt(int min, int max)
- {
- if (max <= 0 ||
- min > max)
- {
- return 0;
- }
-
- return lastUsedRandomGenerator.Next(min, max);
- }
- #endregion
-
- #region RandomFloat (Static)
- /// <summary>
- /// Get random float between min and max (exclusive max)
- /// </summary>
- /// <param name="rnd">Rnd</param>
- /// <param name="min">Min</param>
- /// <param name="max">Max</param>
- /// <returns>Float</returns>
- public static float RandomFloat(this Random rnd, float min, float max)
- {
- return (float)rnd.NextDouble() * (max - min) + min;
- }
-
- /// <summary>
- /// Get random float between min and max (exclusive max)
- /// </summary>
- /// <param name="min">Minimum</param>
- /// <param name="max">Maximum</param>
- /// <returns>Float</returns>
- public static float RandomFloat(float min, float max)
- {
- return (float)lastUsedRandomGenerator.NextDouble() * (max - min) + min;
- }
- #endregion
-
- #region RandomByte (Static)
- /// <summary>
- /// Get random byte between min and max (exclusive max)
- /// </summary>
- /// <param name="rnd">Rnd</param>
- /// <param name="min">Min</param>
- /// <param name="max">Max</param>
- /// <returns>Byte</returns>
- public static byte RandomByte(this Random rnd, byte min, byte max)
- {
- return (byte)(rnd.Next(min, max));
- }
- #endregion
-
- #region RandomVector (Static)
- /// <summary>
- /// Get random vector between min and max for all components.
- /// </summary>
- /// <param name="min">Minimum</param>
- /// <param name="max">Maximum</param>
- /// <returns>Vector</returns>
- public static Vector RandomVector(float min, float max)
- {
- return new Vector(RandomFloat(min, max), RandomFloat(min, max),
- RandomFloat(min, max));
- }
-
- /// <summary>
- /// Get random vector between min and max for each component separated.
- /// </summary>
- /// <param name="minX">Minimum X</param>
- /// <param name="maxX">Maximum X</param>
- /// <param name="minY">Minimum Y</param>
- /// <param name="maxY">Maximum Y</param>
- /// <param name="minZ">Minimum Z</param>
- /// <param name="maxZ">Maximum Z</param>
- /// <returns>Vector</returns>
- public static Vector RandomVector(float minX, float maxX,
- float minY, float maxY, float minZ, float maxZ)
- {
- return new Vector(RandomFloat(minX, maxX), RandomFloat(minY, maxY),
- RandomFloat(minZ, maxZ));
- }
- #endregion
-
- #region CreateRandomBytes (Static)
- /// <summary>
- /// Creates random byte array with given length. Used to generate private
- /// keys and crypto IV values.
- /// </summary>
- /// <param name="length">Length of the byte array we return</param>
- /// <returns>Byte array with random byte data</returns>
- public static byte[] CreateRandomBytes(int length)
- {
- byte[] random = new byte[length];
- RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
- // The array is now filled with cryptographically strong random bytes.
- rng.GetBytes(random);
- return random;
- }
- #endregion
-
- #region CreateRandomString (Static)
- /// <summary>
- /// Create random string, helper for GetFreeUnusedSerial()
- /// and RequestActivationKey(), use SerialLength or
- /// ActivationKeyLength as lengths!
- /// </summary>
- public static string CreateRandomString(int length)
- {
- // RNGCryptoServiceProvider is an implementation of a random number
- // generator. It will produce strong random numbers, so this is very
- // useful for us ^^
- byte[] random = new byte[length];
- RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
- // The array is now filled with cryptographically strong random bytes.
- rng.GetBytes(random);
-
- string s = "";
- for (int i = 0; i < length; i++)
- {
- // We assume Win32Function.GetPerformanceCounter()
- // will change VERY often, so we never get the same values!
- Random rnd = new Random(i + (int)DateTime.Now.Ticks);
- int type = (rnd.Next(36 * 7) + random[i]) % (10 + 26);
- char charType = (char)(type < 10
- ? '0' + type
- : 'A' + (type - 10));
- // Update 2004-10-21: Don't allow any 0 (Zero) or O (Oh) symbols
- if (charType == '0')
- {
- // Replace 0 with random number from 1 to 9
- charType = (char)('1' + rnd.Next(9));
- }
- else if (charType == 'O')
- {
- // Replace O with random letter from A to A+10
- charType = (char)('A' + rnd.Next(10));
- }
- s += charType;
-
- // Do some random execution to make next random value more random
- int rndExecutions = rnd.Next(200);
- for (int j = 0; j < rndExecutions; j++)
- {
- type++;
- }
- }
- return s;
- }
- #endregion
-
- #region CreateRandomStringNoNumbers (Static)
- /// <summary>
- /// Create random string, helper for GetFreeUnusedSerial()
- /// and RequestActivationKey(), use SerialLength or
- /// ActivationKeyLength as lengths!
- /// </summary>
- public static string CreateRandomStringNoNumbers(int length)
- {
- // RNGCryptoServiceProvider is an implementation of a random number
- // generator. It will produce strong random numbers, so this is very
- // useful for us ^^
- byte[] random = new byte[length];
- RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
- // The array is now filled with cryptographically strong random bytes.
- rng.GetBytes(random);
-
- string s = "";
- for (int i = 0; i < length; i++)
- {
- // We assume Win32Function.GetPerformanceCounter()
- // will change VERY often, so we never get the same values!
- Random rnd = new Random(i + (int)DateTime.Now.Ticks);
- int type = (rnd.Next(26 * 7) + random[i]) % (26);
- char charType = (char)('A' + type);
- s += charType;
-
- // Do some random execution to make next random value more random
- int rndExecutions = rnd.Next(200);
- for (int j = 0; j < rndExecutions; j++)
- {
- type++;
- }
- }
- return s;
- }
- #endregion
-
- #region RandomizeIds (Static)
- /// <summary>
- /// Randomize ids
- /// </summary>
- /// <param name="inputIds">Input ids</param>
- /// <returns>List</returns>
- public static List<int> RandomizeIds(List<int> inputIds)
- {
- // Just go through the whole list and swap entries randomly (good enough
- // approach here, will not be 100% even, but looks pretty random).
- for (int num = inputIds.Count - 1; num > 0; num--)
- {
- int newIndex = RandomInt(num);
- // Swap the values
- int swapId = inputIds[newIndex];
- inputIds[newIndex] = inputIds[num];
- inputIds[num] = swapId;
- }
-
- // Return the results
- return inputIds;
- }
-
- /// <summary>
- /// Randomize ids
- /// </summary>
- /// <param name="inputIds">Input ids</param>
- /// <param name="maxCount">Maximum count</param>
- /// <returns>List</returns>
- public static List<int> RandomizeIds(List<int> inputIds,
- int maxCount)
- {
- // Just go through the whole list and swap entries randomly (good enough
- // approach here, will not be 100% even, but looks pretty random).
- for (int num = maxCount - 1; num > 0; num--)
- {
- int newIndex = RandomInt(num);
- // Swap the values
- int swapId = inputIds[newIndex];
- inputIds[newIndex] = inputIds[num];
- inputIds[num] = swapId;
- }
-
- // Return the results
- return inputIds;
- }
- #endregion
-
- #region GetRandomValueWithFactors (Static)
- /// <summary>
- /// Very nice function to calc random value with help of
- /// factors, e.g. when calling with { 0.1f, 0.1f, 2.0f }
- /// we will most likly (in >99% of all cases) get 2 as
- /// result and not 0 or 1!
- /// </summary>
- public static int GetRandomValueWithFactors(List<int> factorArray)
- {
- if (factorArray == null ||
- factorArray.Count == 0)
- {
- return 0;
- }
-
- // Count all factor values
- int allValuesTogether = 0;
- for (int i = 0; i < factorArray.Count; i++)
- {
- allValuesTogether += factorArray[i];
- }
-
- // Now calc random value from 0 to allValuesTogehter
- int rndValue = RandomInt(allValuesTogether);
-
- // Now all we have to do is to check out to which entry
- // the rndValue belongs to
- int currentValue = 0;
- for (int i = 0; i < factorArray.Count; i++)
- {
- if (rndValue >= currentValue &&
- rndValue < currentValue + factorArray[i])
- {
- return i;
- }
- currentValue += factorArray[i];
- }
-
- return 0;
- }
- #endregion
-
- #region RandomizeList (Static)
- /// <summary>
- /// Randomize list
- /// </summary>
- /// <param name="list">List</param>
- /// <param name="maxCount">Maximum count</param>
- /// <returns>List</returns>
- public static List<ListType> RandomizeList<ListType>(
- List<ListType> list, int maxCount)
- {
- List<ListType> ret = new List<ListType>();
- int maximum = 0;
- for (int i = list.Count - 1; i > 0; i--)
- {
- int swapIndex = RandomInt(i + 1);
- if (swapIndex != i)
- {
- ListType tmp = list[swapIndex];
- list[swapIndex] = list[i];
- list[i] = tmp;
- }
- }
-
- if (maxCount > list.Count)
- {
- maximum = list.Count;
- }
- else
- {
- maximum = maxCount;
- }
-
- for (int j = 0; j < maximum; j++)
- {
- ret.Add(list[j]);
- }
-
- return ret;
- }
- #endregion
-
- #region Private
-
- #region lastUsedRandomGenerator (Private)
- /// <summary>
- /// Last used random generator
- /// </summary>
- private static Random lastUsedRandomGenerator = GetNewRandomGenerator();
- #endregion
-
- #endregion
- }
- }