c# - Math.NET CryptoRandomSource Next 是有偏差的

标签 c# random math.net

我正在开发一个受到严格监管审查的游戏平台。我选择 Math.NET 因为它看起来很合适。不过,我刚刚收到我们审计员发回的评论。

请评论这是否准确以及如何解决?


在RandomSource()中,Next(int, int)定义如下:

    public override sealed int Next(int minValue, int maxValue)
    {
        if (minValue > maxValue)
        {
            throw new ArgumentException(Resources.ArgumentMinValueGreaterThanMaxValue);
        }

        if (_threadSafe)
        {
            lock (_lock)
            {
                return (int)(DoSample()*(maxValue - minValue)) + minValue;
            }
        }

        return (int)(DoSample()*(maxValue - minValue)) + minValue;
    }

这会以与之前相同的方式产生偏差。使用 RNG 中的未缩放值并将其乘以范围,而无需事先消除偏差(除非范围是 2 的幂,否则将存在偏差)。

最佳答案

更新:Math.NET Numerics v3.13 中 Next(minInclusive, maxExclusive) 的实现已更改如下这次讨论。从 v3.13 开始,它不再涉及 float ,而是根据需要使用尽可能多的位对整数进行采样,以支持请求的范围(2 的幂)并拒绝实际范围之外的那些。这样就可以避免在字节采样本身之上添加任何偏差(例如由加密 RNG 提供的)

假设:DoSample()返回[0,1)范围内均匀分布的样本( double float )。

将其与范围 R=max-min 相乘将得到范围 [0,R) 内均匀分布的样本。将其转换为整数(本质上是下限)将产生 0,1,2,...,R-1 之一的均匀分布离散样本。我不认为 R 是偶数、奇数或 2 的幂这一事实可能会影响此步骤中的偏差。

计算 100'000'000 个样本的几次运行也没有表明明显的偏差,但这当然不是证据:

var r = new CryptoRandomSource();
long[] h = new long[8];
for (int i = 0; i < 100000000; i++)
{
    h[r.Next(2,7)]++;
}

0
0
19996313
20001286
19998092
19998328
20005981
0

0
0
20000288
20002035
20006269
19994927
19996481
0

0 
0 
19998296 
19997777 
20001463 
20002759 
19999705 
0 

关于c# - Math.NET CryptoRandomSource Next 是有偏差的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39013455/

相关文章:

c# - 对多参数函数使用 Math.NET 的 Fit.Polynomial 方法

c# - Thread.Join 与 Task.Wait

ios - 理解 iOS Swift 2 中的随机数

c# - 对列表中对象的属性使用 Math.NET 统计函数的最佳方法

powershell - 在powershell中从一个范围内生成一个随机数,但不包括1

Java随机数

c# - 在 mathdotnet 中解析具有双系数值的表达式

c# - 为什么我必须在 ASP.NET MVC 中进行 "wire up"依赖注入(inject)?

c# - 在 C# 中对列表进行排序

c# - 您如何使用 ADAL/OAuth 对 CRM Online 进行身份验证并通过 token 请求数据?