San*_*NET 2 .net vb.net random cryptography
我已经通过以下编码来生成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
Run Code Online (Sandbox Code Playgroud)
它显示错误:
指数超出范围.必须是非负数且小于集合的大小.参数名称:
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
Run Code Online (Sandbox Code Playgroud)
第二个参数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);
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
这段代码有两个缺点:
RNGCryptoServiceProvider.GetBytes很大.为了获得更好的性能,请使用几千字节的缓冲区,并且只有GetBytes在用完时才调用.它并不完全一致,但偏差应该足够小,适合大多数应用.
即使使用count显示最大偏差的值,您也需要超过100亿个样本来检测它,而System.Random少数样本就足够了.即偏差约为80亿倍System.Random.
如果您无法接受任何一个弱点,您可以查看我的随机数生成器项目,该项目提供快速,安全且无偏的数字.但这是以添加外部库而不是简单地编写几行代码为代价的.
| 归档时间: |
|
| 查看次数: |
2241 次 |
| 最近记录: |