Skip to content

Instantly share code, notes, and snippets.

@gubed
Last active September 8, 2018 15:43
Show Gist options
  • Save gubed/1a932d5d3c7270bd57ac to your computer and use it in GitHub Desktop.
Save gubed/1a932d5d3c7270bd57ac to your computer and use it in GitHub Desktop.
A secure alternative to System.Random
class SecureRandom : RandomNumberGenerator
{
private readonly RandomNumberGenerator rng;
public SecureRandom()
{
this.rng = new RNGCryptoServiceProvider();
}
public int Next()
{
var data = new byte[sizeof(int)];
rng.GetBytes(data);
return BitConverter.ToInt32(data, 0) & (int.MaxValue - 1);
}
public SecureString String(int len, string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890")
{
SecureString sb = new SecureString();
string letter = string.Empty;
while (sb.Length != len)
{
while (string.IsNullOrEmpty(letter) || !charset.Contains(letter))
{
if (sb.Length == len)
{
sb.MakeReadOnly();
return sb;
}
byte[] oneByte = new byte[1];
rng.GetBytes(oneByte);
char c = (char)oneByte[0];
if (char.IsDigit(c) || char.IsLetter(c))
letter = c.ToString();
}
sb.AppendChar(letter[0]);
letter = string.Empty;
}
sb.MakeReadOnly();
return sb;
}
public int Next(int maxValue)
{
return Next(0, maxValue);
}
public int Next(int minValue, int maxValue)
{
return (int)Math.Floor((minValue + ((double)maxValue - minValue) * NextDouble()));
}
public double NextDouble()
{
var data = new byte[sizeof(uint)];
rng.GetBytes(data);
var randUint = BitConverter.ToUInt32(data, 0);
return randUint / (uint.MaxValue + 1.0);
}
public double NextDouble(double minimum, double maximum)
{
return NextDouble() * (maximum - minimum) + minimum;
}
public override void GetBytes(byte[] data)
{
rng.GetBytes(data);
}
public override void GetNonZeroBytes(byte[] data)
{
rng.GetNonZeroBytes(data);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment