Last active
November 23, 2015 22:56
-
-
Save archer884/a9f2e00df35216fa9ea8 to your computer and use it in GitHub Desktop.
For posterity...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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