Skip to content

Instantly share code, notes, and snippets.

@mjs3339
Last active February 11, 2019 05:06
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 mjs3339/a3d967a77227d30a99584443179cccc4 to your computer and use it in GitHub Desktop.
Save mjs3339/a3d967a77227d30a99584443179cccc4 to your computer and use it in GitHub Desktop.
C# Crypto Random Number Generator Includes BigInteger
[Serializable]
public class CryptoRandomNumberGenerator : RandomNumberGenerator
{
private const double DBi = 5.42101086242752E-20D;
private readonly RNGCryptoServiceProvider crng = new RNGCryptoServiceProvider();
public char NextChar()
{
return(char) (Sample() * char.MaxValue);
}
public char NextChar(char maxValue)
{
if(maxValue == 0)
throw new ArgumentException("maxValue must be greater than zero.");
return(char) (Sample() * maxValue);
}
public char NextChar(char minValue, char maxValue)
{
if(maxValue < minValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
return(char) (Sample() * (maxValue - minValue) + minValue);
}
public sbyte NextSByte()
{
return(sbyte) (Sample() * sbyte.MaxValue);
}
public sbyte NextSByte(int maxValue)
{
if(maxValue == 0)
throw new ArgumentException("maxValue must be greater than zero.");
return(sbyte) (Sample() * maxValue);
}
public sbyte NextSByte(int minValue, int maxValue)
{
if(maxValue < minValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
return(sbyte) (Sample() * (maxValue - minValue) + minValue);
}
public byte NextByte()
{
return(byte) (Sample() * byte.MaxValue);
}
public byte NextByte(int maxValue)
{
if(maxValue == 0)
throw new ArgumentException("maxValue must be greater than zero.");
return(byte) (Sample() * maxValue);
}
public byte NextByte(int minValue, int maxValue)
{
if(maxValue < minValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
return(byte) (Sample() * (maxValue - minValue) + minValue);
}
public short NextShort()
{
return(short) (Sample() * short.MaxValue);
}
public short NextShort(int maxValue)
{
if(maxValue == 0)
throw new ArgumentException("maxValue must be greater than zero.");
return(short) (Sample() * maxValue);
}
public short NextShort(int minValue, int maxValue)
{
if(maxValue < minValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
return(short) (Sample() * (maxValue - minValue) + minValue);
}
public ushort NextUShort()
{
return(ushort) (Sample() * ushort.MaxValue);
}
public ushort NextUShort(int maxValue)
{
if(maxValue == 0)
throw new ArgumentException("maxValue must be greater than zero.");
return(ushort) (Sample() * maxValue);
}
public ushort NextUShort(int minValue, int maxValue)
{
if(maxValue < minValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
return(ushort) (Sample() * (maxValue - minValue) + minValue);
}
public int NextInt()
{
return(int) (Sample() * int.MaxValue);
}
public int NextInt(int maxValue)
{
if(maxValue == 0)
throw new ArgumentException("maxValue must be greater than zero.");
return(int) (Sample() * maxValue);
}
public int NextInt(int minValue, int maxValue)
{
if(maxValue < minValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
return(int) (Sample() * (maxValue - minValue) + minValue);
}
public uint NextUInt()
{
return(uint) (Sample() * uint.MaxValue);
}
public uint NextUInt(uint maxValue)
{
if(maxValue == 0)
throw new ArgumentException("maxValue must be greater than zero.");
return(uint) (Sample() * maxValue);
}
public uint NextUInt(uint minValue, uint maxValue)
{
if(maxValue < minValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
return(uint) (Sample() * (maxValue - minValue) + minValue);
}
public long NextLong()
{
return(long) (Sample() * long.MaxValue);
}
public long NextLong(long maxValue)
{
if(maxValue == 0)
throw new ArgumentException("maxValue must be greater than zero.");
return(long) (Sample() * maxValue);
}
public long NextLong(long minValue, long maxValue)
{
if(maxValue < minValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
return(long) (Sample() * (maxValue - minValue) + minValue);
}
public ulong NextULong()
{
return(ulong) (Sample() * ulong.MaxValue);
}
public ulong NextULong(ulong maxValue)
{
if(maxValue == 0)
throw new ArgumentException("maxValue must be greater than zero.");
return(ulong) (Sample() * maxValue);
}
public ulong NextULong(ulong minValue, ulong maxValue)
{
if(maxValue < minValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
return(ulong) (Sample() * (maxValue - minValue) + minValue);
}
public BigInteger NextBigInteger(int BitLength = 128)
{
return BigSample(BitLength);
}
public BigInteger NextBigUnsignedInteger(int BitLength = 128)
{
return BigUSample(BitLength);
}
public BigInteger NextBigInteger(int MinBitLength, int MaxBitLength)
{
return BigSample(MinBitLength, MaxBitLength);
}
public BigInteger NextBigUnsignedInteger(int MinBitLength, int MaxBitLength)
{
return BigUSample(MinBitLength, MaxBitLength);
}
public float NextFloat(float minValue, float maxValue)
{
if(maxValue < minValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
while(true)
{
var value = (float) (Sample() * (maxValue - minValue) + minValue);
if(!float.IsNaN(value) && !float.IsInfinity(value))
return value;
}
}
public float NextFloat()
{
return(float) Sample();
}
public double NextDouble(double minValue, double maxValue)
{
if(maxValue < minValue)
throw new ArgumentException("maxValue must be greater than or equal to minValue");
while(true)
{
var value = Sample() * (maxValue - minValue) + minValue;
if(!double.IsNaN(value) && !double.IsInfinity(value))
return value;
}
}
public double NextDouble()
{
return Sample();
}
private double Sample()
{
var buf = new byte[8];
GetBytes(buf);
var sr = buf.ToULong();
return sr * DBi;
}
private BigInteger BigSample(int BitLength)
{
var buf = new byte[BitLength >> 3];
GetBytes(buf);
var val = new BigInteger(buf);
return val;
}
private BigInteger BigUSample(int BitLength)
{
BigInteger n;
var buf = new byte[BitLength >> 3];
do
{
GetBytes(buf);
n = new BigInteger(buf);
} while(n.Sign == -1);
return n;
}
private BigInteger BigSample(int MinBitLength, int MaxBitLength)
{
if(MinBitLength % 8 != 0)
throw new Exception("The Minimum Bit Length must be a multiple of 8.");
if(MaxBitLength % 8 != 0)
throw new Exception("The Maximum Bit Length must be a multiple of 8.");
if(MinBitLength < 8)
throw new Exception("The Minimum Bit Length must be at least 8.");
if(MinBitLength > MaxBitLength)
throw new Exception("Minimum Bit Length Exceeds Maximum Bit Length.");
int BitLength;
if(MinBitLength == MaxBitLength)
BitLength = MaxBitLength;
else
BitLength = NextUShort(1, ((MaxBitLength - MinBitLength) >> 3) + 1) << 3;
var byteLength = BitLength >> 3;
if(byteLength <= 0)
byteLength = 1;
var buf = new byte[byteLength];
GetBytes(buf);
var val = new BigInteger(buf);
return val;
}
private BigInteger BigUSample(int MinBitLength, int MaxBitLength)
{
if(MinBitLength % 8 != 0)
throw new Exception("The Minimum Bit Length must be a multiple of 8.");
if(MaxBitLength % 8 != 0)
throw new Exception("The Maximum Bit Length must be a multiple of 8.");
if(MinBitLength < 8)
throw new Exception("The Minimum Bit Length must be at least 8.");
if(MinBitLength > MaxBitLength)
throw new Exception("Minimum Bit Length Exceeds Maximum Bit Length.");
int BitLength;
if(MinBitLength == MaxBitLength)
BitLength = MaxBitLength;
else
BitLength = NextUShort(1, ((MaxBitLength - MinBitLength) >> 3) + 1) << 3;
var byteLength = BitLength >> 3;
if(byteLength <= 0)
byteLength = 1;
var buf = new byte[byteLength];
BigInteger n;
do
{
GetBytes(buf);
n = new BigInteger(buf);
} while(n.Sign == -1);
return n;
}
public override void GetBytes(byte[] data)
{
crng.GetBytes(data);
}
public byte GetNextByte()
{
var xbc = new byte[1];
crng.GetBytes(xbc);
return xbc[0];
}
public char GetNextChar()
{
var xbc = new byte[1];
while(true)
{
crng.GetBytes(xbc);
var c = xbc[0];
if(c >= 32 || c <= 127)
return(char) c;
}
}
public byte[] GetNextByteArray(int size)
{
var ba = new byte[size];
crng.GetBytes(ba);
return ba;
}
public char[] GetNextCharArray(int size)
{
var xbc = new byte[1];
var ca = new char[size];
var ptr = 0;
do
{
crng.GetBytes(xbc);
var c = xbc[0];
if(c >= 32 || c <= 127)
ca[ptr++] = (char) c;
} while(ptr < size);
return ca;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment