Skip to content

Instantly share code, notes, and snippets.

@archer884
Last active November 23, 2015 22:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save archer884/a9f2e00df35216fa9ea8 to your computer and use it in GitHub Desktop.
Save archer884/a9f2e00df35216fa9ea8 to your computer and use it in GitHub Desktop.
For posterity...
using System;
using System.Security.Cryptography;
namespace JA
{
// Credit for CryptoRandom goes to Stephen Toub & Shawn Farkas, original
// authors of the code included below, which appeared in September 2007
// in MSDN Magazine.
//
// http://blogs.msdn.com/b/msdnmagazine/archive/2007/08/31/4653696.aspx
/// <summary>
/// Wraps <see cref="RNGCryptoServiceProvider"/> to generate cryptographically strong
/// random number generator presenting the same interface as <see cref="Random"/>.
/// </summary>
public class CryptoRandom : Random
{
private RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider();
private byte[] _uint32Buffer = new byte[4];
public CryptoRandom() { }
public CryptoRandom(Int32 ignoredSeed) { }
/// <summary>
/// Returns a nonnegative random integer.
/// </summary>
public override Int32 Next()
{
_rng.GetBytes(_uint32Buffer);
return BitConverter.ToInt32(_uint32Buffer, 0) & 0x7FFFFFFF;
}
/// <summary>
/// Returns a nonnegative random integer that is less than the specified maximum.
/// </summary>
/// <param name="maxValue">The exclusive upper bound of the random number to be generated. maxValue must be greater than or equal to zero.</param>
public override Int32 Next(Int32 maxValue)
{
if (maxValue < 0) throw new ArgumentOutOfRangeException("maxValue");
return Next(0, maxValue);
}
/// <summary>
/// Returns a random integer that is within a specified range.
/// </summary>
/// <param name="minValue">The inclusive lower bound of the random number returned.</param>
/// <param name="maxValue">The exclusive upper bound of the random number returned. maxValue must be greater than or equal to zero.</param>
public override Int32 Next(Int32 minValue, Int32 maxValue)
{
if (minValue > maxValue) throw new ArgumentOutOfRangeException("minValue");
if (minValue == maxValue) return minValue;
Int64 diff = maxValue - minValue;
while (true)
{
_rng.GetBytes(_uint32Buffer);
UInt32 rand = BitConverter.ToUInt32(_uint32Buffer, 0);
Int64 max = (1 + (Int64)UInt32.MaxValue);
Int64 remainder = max % diff;
if (rand < max - remainder)
{
return (Int32)(minValue + (rand % diff));
}
}
}
/// <summary>
/// Returns a random floating point number between 0.0 and 1.0.
/// </summary>
public override double NextDouble()
{
_rng.GetBytes(_uint32Buffer);
UInt32 rand = BitConverter.ToUInt32(_uint32Buffer, 0);
return rand / (1.0 + UInt32.MaxValue);
}
/// <summary>
/// Fills the elements of a specified array of bytes with random numbers.
/// </summary>
/// <param name="buffer">An array of bytes to contain random numbers.</param>
public override void NextBytes(byte[] buffer)
{
if (buffer == null) throw new ArgumentNullException("buffer");
_rng.GetBytes(buffer);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment