46 lines
1.3 KiB
C#
46 lines
1.3 KiB
C#
|
using System;
|
||
|
using System.Security.Cryptography;
|
||
|
|
||
|
namespace Geekbot.net.Lib.RandomNumberGenerator
|
||
|
{
|
||
|
public class RandomNumberGenerator : IRandomNumberGenerator
|
||
|
{
|
||
|
readonly RNGCryptoServiceProvider csp;
|
||
|
|
||
|
public RandomNumberGenerator()
|
||
|
{
|
||
|
csp = new RNGCryptoServiceProvider();
|
||
|
}
|
||
|
|
||
|
public int Next(int minValue, int maxExclusiveValue)
|
||
|
{
|
||
|
if (minValue >= maxExclusiveValue)
|
||
|
{
|
||
|
throw new ArgumentOutOfRangeException("minValue must be lower than maxExclusiveValue");
|
||
|
}
|
||
|
|
||
|
var diff = (long)maxExclusiveValue - minValue;
|
||
|
var upperBound = uint.MaxValue / diff * diff;
|
||
|
|
||
|
uint ui;
|
||
|
do
|
||
|
{
|
||
|
ui = GetRandomUInt();
|
||
|
} while (ui >= upperBound);
|
||
|
return (int)(minValue + (ui % diff));
|
||
|
}
|
||
|
|
||
|
private uint GetRandomUInt()
|
||
|
{
|
||
|
var randomBytes = GenerateRandomBytes(sizeof(uint));
|
||
|
return BitConverter.ToUInt32(randomBytes, 0);
|
||
|
}
|
||
|
|
||
|
private byte[] GenerateRandomBytes(int bytesNumber)
|
||
|
{
|
||
|
var buffer = new byte[bytesNumber];
|
||
|
csp.GetBytes(buffer);
|
||
|
return buffer;
|
||
|
}
|
||
|
}
|
||
|
}
|