49 lines
1.7 KiB
C#
49 lines
1.7 KiB
C#
using System;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace CKS.FormsBasedAuthentication.HIP
|
|
{
|
|
/// <summary>Provides cryptographically-strong pseudo-random numbers.</summary>
|
|
internal class RandomNumbers
|
|
{
|
|
/// <summary>Random number generator.</summary>
|
|
private RNGCryptoServiceProvider _rand = new RNGCryptoServiceProvider();
|
|
|
|
/// <summary>Used by NextRandom and NextRandomDouble.</summary>
|
|
/// <remarks>
|
|
/// RNGCryptoServiceProvider is not thread-safe. Therefore, we only call to on a single thread.
|
|
/// As a result, we can resuse the same byte arrays for every call.
|
|
/// </remarks>
|
|
private byte [] _rd4 = new byte[4], _rd8 = new byte[8];
|
|
|
|
/// <summary>Gets a random non-negative integer less than max.</summary>
|
|
/// <param name="max">The upper-bound for the random number.</param>
|
|
/// <returns>The generated random number.</returns>
|
|
public int Next(int max)
|
|
{
|
|
if (max <= 0) throw new ArgumentOutOfRangeException("max");
|
|
_rand.GetBytes(_rd4);
|
|
int val = BitConverter.ToInt32(_rd4, 0) % max;
|
|
if (val < 0) val = -val;
|
|
return val;
|
|
}
|
|
|
|
/// <summary>Gets a random number between min and max, inclusive.</summary>
|
|
/// <param name="min">The minimum possible value.</param>
|
|
/// <param name="max">The maximum possible value.</param>
|
|
/// <returns>The randomly generated number.</returns>
|
|
public int Next(int min, int max)
|
|
{
|
|
if (min > max) throw new ArgumentOutOfRangeException("max");
|
|
return Next(max - min + 1) + min;
|
|
}
|
|
|
|
/// <summary>Gets a randomly generated double between 0.0 and 1.1.</summary>
|
|
/// <returns>The random number.</returns>
|
|
public double NextDouble()
|
|
{
|
|
_rand.GetBytes(_rd8);
|
|
return BitConverter.ToUInt64(_rd8, 0) / (double)UInt64.MaxValue;
|
|
}
|
|
}
|
|
} |