【问题标题】:Using RNGCryptoServiceProvider to "simulate" throwing a dice使用 RNGCryptoServiceProvider 来“模拟”掷骰子
【发布时间】:2015-08-09 15:46:49
【问题描述】:

我一直在尝试在 C# 中模拟滚动 6 面骰子。我认为使用 RNGCSP 比 Random 更好,因为它更安全。

我尝试使用MSDN's example code 来实现这一点,但是我从代码中没有理解一些事情:

  1. 如何使用 RNGCSP 生成 5 位长数字?
  2. 如何生成从 1 到 6 的数字(不包括零)?

【问题讨论】:

  • 模拟掷骰子需要多少安全性?
  • 我需要它是完全随机的。
  • "如何生成从 1 到 6 的数字(不包括零)?"该示例仅使用mod operator %return (byte)((randomNumber[0] % numberSides) + 1);
  • 是的,mod 操作员解决了骰子问题,并且通过更多的工作,5 位数的问题让大多数人感到满意。但是,如果随机性非常很重要,则需要考虑一些额外的问题。如果 RNGCSP 返回一个字节,它的值可以是 0 到 255。所以你修改它 6 并加 1。但是这样做,在该字节的 256 个可能值中,使用 Idle_Mind 的公式产生 1、2、3 或 4 的值将在 256 次中出现 43 次。 5 和 6 在 256 次中各只出现 42 次。因此,在使用 mod 之前,您应该丢弃任何字节值 252-255 并重新滚动它。
  • @Preston Guillot:如果您经营的是在线赌场或类似的赌场,那么您的随机数需要 100% 安全。如果您的掷骰子表现出任何偏差,那么某个地方的某个人会注意到并带您去清洁工。

标签: c# cryptography


【解决方案1】:

1.如何使用 RNGCSP 生成 5 位长数字?

对于数字,您可以使用范围。不过,您必须自己考虑下限。数字范围在RNGCryptoServiceProvider 中处理。

所以对于 5 位数字,min 将是 010000max 将是 100000,因为 max专有的

2。如何生成 1 到 6 的数字(不包括零)?

基本上以相同的方式生成一个范围 [1, 7),其中 7(max 值)是独占的。

如果你只是想要一个骰子结果,你可以这样做(未经测试!):

RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] singleByteBuf = new byte[1];
int max = Byte.MaxValue - Byte.MaxValue % 6;
while (true) {
    rng.GetBytes(singleByteBuf);
    int b = singleByteBuf[0];
    if (b < max) {
        return b % 6 + 1;
    }
 }

基本相同的想法,但是一次只从RNGCryptoServiceProvider请求1个字节,所以它不会浪费3个额外的字节。

【讨论】:

    猜你喜欢
    • 2011-07-12
    • 2018-01-03
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 2016-04-18
    • 1970-01-01
    • 2011-01-19
    相关资源
    最近更新 更多