从随机字节生成给定范围内的随机数

时间:2016-11-04 14:29:56

标签: algorithm random cryptography numeric-ranges

有类似的问题,但大部分都是语言特定的。我正在寻找一般的解决方案。给定一些生成 k 随机字节和数字 n 的方法,我需要生成一个范围 1 ... n (含)的随机数)。

到目前为止,我提出了什么:

  1. 要确定表示 n 所需的字节数,请计算
  2. f(n):=ceiling(ln(n)/8ln(2))=ceiling(0.180337*ln(n))

    1. 获取范围 1 ... 2 ^ 8f(n)范围内的随机数,用于0索引字节b [i]:
    2. r:=0 for i=0 to k-1: r = r + b[i] * 2^(8*i) end for

      1. 无偏见地缩放到 1 ... n

        R(n,r) := ceiling(n * (r / 256^f(n)))

      2. 但我不确定这不会造成偏见或某种微妙的一次性错误。你能检查一下这个声音和/或提出改进建议吗?这是正确的方法吗?

        在答案中,请假设没有可用的模块化比特操作,但您可以假设任意精度算术。 (我在Scheme中编程。)

        编辑:我的方法肯定有问题,因为在我的测试中掷骰子产生了一些0的情况!但错误在哪里?

1 个答案:

答案 0 :(得分:1)

这与您想要从0到1(包括0和1)的随机浮点数生成从1到n的数字类似。如果r是随机浮点数:

result = (r * n) + 1

如果您有任意精度算术,则可以通过将k字节整数除以r字节中可表达的最大值+ 1来计算k

因此,如果您有4个字节87 6F BD 4A,并且n = 200:

((0x876FBd4A/0x100000000) * 200) + 1