首页 文章

如何使用RNGCryptoServiceProvider获取大于256的随机数?

提问于
浏览
0

如何使用RNGCryptoServiceProvider获得大于256的随机数?

Code:

private static RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();

byte[] randomNumber = new byte[1];

//Fill the array with a random value.   

rngCsp.GetBytes(randomNumber);

2 回答

  • 3

    填充1到8个字节的数组,并使用BitConverter提取整数 .

    static ulong RandomUInt64()
        {
            var rng = new RNGCryptoServiceProvider();
            var bytes = new byte[8];
            rng.GetBytes(bytes);
            return BitConverter.ToUInt64(bytes);
        }
    

    如果要生成特定范围内的随机数并且还想保留分布,则应生成一系列数字并丢弃不在预期范围内的值(蒙特卡罗方法) . 我怀疑如果你正在考虑一个安全的加密随机数生成器,这就是你想要的行为 .

    static int Random(RandomNumberGenerator rng, int min, int max)
        {
            if (min > max) throw new ArgumentException(nameof(min));
            if (min == max) return min;
    
            var bytes = new byte[4];
    
            long diff = max - min;
    
            while (true)
            {
                rng.GetBytes(bytes);
    
                var rand = BitConverter.ToUInt32(bytes);
                var remainder = (1 + (long) uint.MaxValue) % diff;
    
                if (rand < max - remainder)
                {
                    return (int) (min + (rand % diff));
                }
            }
        }
    

    有可能在任意范围内生成随机数,并通过对随机样本的归一化表示执行线性变换来保留分布,但我不确定数学 .

    static int Random(RandomNumberGenerator rng, int min, int max)
        {
            if (min > max) throw new ArgumentException(nameof(min));
            if (min == max) return min;
    
            var buffer = new byte[4];
            rng.GetBytes(buffer);
            var value = BitConverter.ToUInt32(buffer, 0);
            var normalizedValue = value / (double)uint.MaxValue;
            return (int)(normalizedValue * (max - min)) + min;
        }
    

    调用提供程序时会产生很大的开销,因此请考虑缓冲对 GetBytes 的调用并使用生成器:

    static IEnumerable<int> Random(RandomNumberGenerator rng, int min, int max)
        {
            if (min > max) throw new ArgumentException(nameof(min));
            if (min == max) return min;
    
            var buffer = new byte[4096];
    
            while (true)
            {
                rng.GetBytes(buffer);
    
                for (var i = 0; i < buffer.Length / 4; i += 4)
                {
                    var value = BitConverter.ToUInt32(buffer, i);
                    var normalizedValue = value / (double)uint.MaxValue;
                    yield return (int)(normalizedValue * (max - min)) + min;
                }
            }
        }
    

    这将为您提供有用的API:

    var rng = new RNGCryptoServiceProvider();
      var randomValues = Random(rng, 0, 100).Take(100).ToArray();
    
  • 6

    您是否有任何理由需要将RNGCryptoServiceProvider用于大于256的随机数?

    按照emert117的描述,字节的最大值为255 .

    如果你需要一个随机数,你可以尝试随机类 .

    Random _randomizer = New Random();
    int randomNumber = _randomizer.Next(0,512);
    

相关问题