I've written an abstract class in C# for the purpose of random number generation from an array of bytes. The .NET class RNGCryptoServiceProvider
can be used to generate this array of random bytes, for example.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyLibrary
{
/// <summary>
/// Represents the abstract base class for a random number generator.
/// </summary>
public abstract class Rng
{
/// <summary>
/// Initializes a new instance of the <see cref="Rng"/> class.
/// </summary>
public Rng()
{
//
}
public Int16 GetInt16(Int16 min, Int16 max)
{
return (Int16)(min + (Int16)(GetDouble() * (max - min)));
}
public Int32 GetInt32(Int32 min, Int32 max)
{
return (Int32)(min + (Int32)(GetDouble() * (max - min)));
}
public Int64 GetInt64(Int64 min, Int64 max)
{
return (Int64)(min + (Int64)(GetDouble() * (max - min)));
}
public UInt16 GetUInt16(UInt16 min, UInt16 max)
{
return (UInt16)(min + (UInt16)(GetDouble() * (max - min)));
}
public UInt32 GetUInt32(UInt32 min, UInt32 max)
{
return (UInt32)(min + (UInt32)(GetDouble() * (max - min)));
}
public UInt64 GetUInt64(UInt64 min, UInt64 max)
{
return (UInt64)(min + (UInt64)(GetDouble() * (max - min)));
}
public Single GetSingle()
{
return (Single)GetUInt64() / UInt64.MaxValue;
}
public Double GetDouble()
{
return (Double)GetUInt64() / UInt64.MaxValue;
}
public Int16 GetInt16()
{
return BitConverter.ToInt16(GetBytes(2), 0);
}
public Int32 GetInt32()
{
return BitConverter.ToInt32(GetBytes(4), 0);
}
public Int64 GetInt64()
{
return BitConverter.ToInt64(GetBytes(8), 0);
}
public UInt16 GetUInt16()
{
return BitConverter.ToUInt16(GetBytes(2), 0);
}
public UInt32 GetUInt32()
{
return BitConverter.ToUInt32(GetBytes(4), 0);
}
public UInt64 GetUInt64()
{
return BitConverter.ToUInt64(GetBytes(8), 0);
}
/// <summary>
/// Generates random bytes of the specified length.
/// </summary>
/// <param name="count">The number of bytes to generate.</param>
/// <returns>The randomly generated bytes.</returns>
public abstract byte[] GetBytes(int count);
}
}
Any suggestions for improvements would be welcome.
min
/max
params require floating-point random numbers. They in turn require integral random numbers to generate. (I see no other way, sinceBitConverter.GetDouble
would skew the distribution.) \$\endgroup\$System.Random
does indeed provide this sort of functionality, but it is specific to an internal PNG (that has poor entropy). The idea is that implementations can derive from this class to implement specific RNG algorithms like the CSP one (RNGCryptoServiceProvider), Mersenne Twister, etc., simply by providing a generator for random bytes. The code above says nothing as to the random bytes are generates. \$\endgroup\$maximum
is exclusive here ;) \$\endgroup\$