我已经使用以下编码来生成1000-9999范围内的范围:
Dim byt As Byte() = New Byte(1000) {}
Dim rngCrypto As New RNGCryptoServiceProvider()
rngCrypto.GetBytes(byt)
Dim randomNumber As Integer = BitConverter.ToInt32(byt, 9999)
Label4.Text = randomNumber
显示错误:
指数超出范围。必须是非负数且小于集合的大小。参数名称:
startIndex
我已经完成了以下代码。这是对的吗?
Public Sub secrand()
Static r As Random = Nothing
If r Is Nothing Then
Dim seed() As Byte = New Byte(4) {}
Dim rng As New RNGCryptoServiceProvider
rng.GetBytes(seed)
r = New Random(BitConverter.ToInt32(seed, 0))
Label4.Text = r.Next(1000, 9999)
End If
End Sub
答案 0 :(得分:5)
BitConverter.ToInt32
的第二个参数是字节数组的偏移量。它应该是0。如果你只使用其中的4个,也没有理由获得1000个字节。
C#中的工作版本:
public static int RandomUniform(int count)
{
if(count <= 0)
throw new ArgumentOutOfRangeException("count");
var rng=new RNGCryptoServiceProvider();
var bytes=new byte[8];
rng.GetBytes(bytes, 0);
return BitConverter.ToUInt64() % (uint)count;
}
Label4.Text = 1000 + RandomUniform(9000);
在VB.net中,这看起来类似于
Public Shared Function RandomUniform(count As Integer) As Integer
If count <= 0 Then
Throw New ArgumentOutOfRangeException("count")
End If
Dim rng = New RNGCryptoServiceProvider()
Dim bytes = New Byte(8) {}
rng.GetBytes(bytes, 0)
Return BitConverter.ToUInt64() Mod CUInt(count)
End Function
此代码有两个缺点:
RNGCryptoServiceProvider.GetBytes
的每次呼叫开销很大。
为了获得更好的性能,请使用几千字节的缓冲区,并在用完时调用GetBytes
。它并不完全一致,但对于大多数应用来说,偏差应该足够小。
即使使用显示最大偏差的count
值,您也需要超过100亿个样本来检测它,而对于System.Random
来说,少数就足够了。即偏差比System.Random
小约80亿倍。
如果您无法接受任何一个弱点,您可以查看我的random number generator project,它提供快速,安全且无偏见的号码。但这是以添加外部库而不是简单地编写几行代码为代价的。