好了,所以我有点迟到派对,但我真的想要一个完整的System.Random实现,可以在同一个定时器tic中多次调用并产生不同的结果。后在不同的实现多痛苦,我看中了,我想出了一个最简单的,它提供了提供了一个随机密钥的基础System.Random构造一个默认的构造函数:
/// <summary> An implementation of System.Random whose default constructor uses a random seed value rather than the system time. </summary>
public class RandomEx : Random
{
/// <summary> Initializes a new CryptoRandom instance using a random seed value. </summary>
public RandomEx()
: base(_GetSeed())
{ }
/// <summary> Initializes a new CryptoRandom instance using the specified seed value. </summary>
/// <param name="seed"> The seed value. </param>
public RandomEx(int seed)
: base(seed)
{ }
// The static (shared by all callers!) RandomNumberGenerator instance
private static RandomNumberGenerator _rng = null;
/// <summary> Static method that returns a random integer. </summary>
private static int _GetSeed()
{
var seed = new byte[sizeof(int)];
lock (typeof(RandomEx)) {
// Initialize the RandomNumberGenerator instance if necessary
if (_rng == null) _rng = new RNGCryptoServiceProvider();
// Get the random bytes
_rng.GetBytes(seed);
}
// Convert the bytes to an int
return BitConverter.ToInt32(seed, 0);
}
}
一路上,我也写和测试,它覆盖所必需的方法中使用RNGCryptoServiceProvider提供所有的随机值(而不是依赖于任何的随机数发生器被烘焙到System.Random类)的实现。但是我不知道在您随机抽取Sample()值并通过变换产生整数值时,结果的密码强度如何。无论如何,这里是代码,如果有人想要它:
/// <summary> An implementation of System.Random that uses RNGCryptoServiceProvider to provide random values. </summary>
public class CryptoRandom : Random, IDisposable
{
// Class data
RandomNumberGenerator _csp = new RNGCryptoServiceProvider();
/// <summary> Returns a random number between 0.0 (inclusive) and 1.0 (exclusive). </summary>
protected override double Sample()
{
// Get a nonnegative random Int64
byte[] bytes = new byte[sizeof(long)];
_csp.GetBytes(bytes);
long value = BitConverter.ToInt64(bytes, 0) & long.MaxValue;
// Scale it to 0->1
return (double)value/(((double)Int64.MaxValue) + 1025.0d);
}
/// <summary> Fills the elements of the 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)
{
_csp.GetBytes(buffer);
}
/// <summary> Returns a nonnegative random integer. </summary>
/// <returns> A 32-bit signed integer greater than or equal to zero. </returns>
public override int Next()
{
byte[] data = new byte[4];
_csp.GetBytes(data);
data[3] &= 0x7f;
return BitConverter.ToInt32(data, 0);
}
/// <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 minValue. </param>
/// <returns> A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values includes minValue but not maxValue. If minValue equals maxValue, minValue is returned. </returns>
public override int Next(int minValue, int maxValue)
{
// Special case
if (minValue == maxValue) return minValue;
double sample = Sample();
double range = (double)maxValue - (double)minValue;
return (int)((sample * (double)range) + (double)minValue);
}
#region IDisposible implementation
/// <summary> Disposes the CryptoRandom instance and all of its allocated resources. </summary>
public void Dispose()
{
// Do the actual work
Dispose(true);
// This object will be cleaned up by the Dispose method. Call GC.SupressFinalize to
// take this object off the finalization queue and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
// Dispose(bool disposing) executes in two distinct scenarios:
//
// If disposing is true, the method has been called directly or indirectly by a user's code and both
// managed and unmanaged resources can be disposed.
//
// If disposing is false, the method has been called by the runtime from inside the finalizer.
// In this case, only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
if (disposing) {
// The method has been called directly or indirectly by a user's code; dispose managed resources (if any)
if (_csp != null) {
_csp.Dispose();
_csp = null;
}
// Dispose unmanaged resources (if any)
}
}
#endregion
}
有没有'随机数'的最佳做法。仅适用于需要随机数的具体情况。 – 2011-02-03 22:47:23