【发布时间】:2016-11-04 14:29:55
【问题描述】:
也有类似的问题,但大多数问题都针对特定语言。我正在寻找一个通用的解决方案。给定一些产生 k 随机字节和数字 n 的方法,我需要产生一个范围为 1...n 的随机数(包括)。
到目前为止我的想法:
- 要确定表示 n 所需的字节数,请计算
f(n):=ceiling(ln(n)/8ln(2))=ceiling(0.180337*ln(n))
- 为 0 索引字节 b[i] 获取范围 1...2^8f(n) 范围内的随机数:
r:=0
for i=0 to k-1:
r = r + b[i] * 2^(8*i)
end for
-
无偏差地缩放到 1...n:
R(n,r) := ceiling(n * (r / 256^f(n)))
但我不确定这不会造成偏见或一些微妙的一次性错误。您能否检查一下这是否合理和/或提出改进建议?这是正确的做法吗?
在答案中,请假设没有可用的模块化位旋转操作,但您可以假设任意精度算术。 (我在 Scheme 中编程。)
编辑:我的方法肯定有问题,因为在我的测试中掷骰子会产生一些 0 的情况!但是错误在哪里?
【问题讨论】:
标签: algorithm random cryptography numeric-ranges