Last active
February 11, 2019 05:06
-
-
Save mjs3339/a3d967a77227d30a99584443179cccc4 to your computer and use it in GitHub Desktop.
C# Crypto Random Number Generator Includes BigInteger
This file contains 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
[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