C# 生成小于Int数值绝对值的随机数
C#中有两种类型的随机数生成器:
- 伪随机数(System.Random)
- 安全随机数(System.Security.Cryptography.RNGCryptoServiceProvider)
关键的区别在于用于进行随机化的种子值可能不会快速且随机地变化。例如,System.Random依赖于计算机系统时钟
public static class IntNumRandom {
/// <summary>
/// 生成小于输入值绝对值的随机数
/// </summary>
/// <param name="NumSides"></param>
/// <returns></returns>
public static int Next (this int numSeeds) {
numSeeds = Math.Abs (numSeeds);
if (numSeeds <= 1) {
return 0;
}
int length = 4;
if (numSeeds <= byte.MaxValue) {
length = 1;
} else if (numSeeds <= short.MaxValue) {
length = 2;
}
return Next (numSeeds, length);
}
private static int Next (int numSeeds, int length) {
// Create a byte array to hold the random value.
byte[] buffer = new byte[length];
// Create a new instance of the RNGCryptoServiceProvider.
System.Security.Cryptography.RNGCryptoServiceProvider Gen = new System.Security.Cryptography.RNGCryptoServiceProvider ();
// Fill the array with a random value.
Gen.GetBytes (buffer);
// Convert the byte to an uint value to make the modulus operation easier.
uint randomResult = 0x0; //这里用uint作为生成的随机数
for (int i = 0; i < length; i++) {
randomResult |= ((uint) buffer[i] << ((length - 1 - i) * 8));
}
// Return the random number mod the number
// of sides. The possible values are zero-based
return (int) (randomResult % numSeeds);
}
}
public class RandomGenerator {
readonly RNGCryptoServiceProvider csp;
public RandomGenerator () {
csp = new RNGCryptoServiceProvider ();
}
public int Next (int minValue, int maxExclusiveValue) {
if (minValue >= maxExclusiveValue)
throw new ArgumentOutOfRangeException ("minValue must be lower than maxExclusiveValue");
long diff = (long) maxExclusiveValue - minValue;
long upperBound = uint.MaxValue / diff * diff;
uint ui;
do {
ui = GetRandomUInt ();
} while (ui >= upperBound);
return (int) (minValue + (ui % diff));
}
public uint GetRandomUInt () {
var randomBytes = GenerateRandomBytes (sizeof (uint));
return BitConverter.ToUInt32 (randomBytes, 0);
}
private byte[] GenerateRandomBytes (int bytesNumber) {
byte[] buffer = new byte[bytesNumber];
csp.GetBytes (buffer);
return buffer;
}
}