2

假设我需要 [0, K) 范围内的 N 个加密安全伪随机整数。实现这一点的最明显方法是 N 调用arc4random_uniform(3),这正是我正在做的。

然而,分析器告诉我,无数次调用arc4random_uniform(3)占用了整个执行时间的 2/3,我真的需要让我的代码更快。这就是为什么我计划提前生成一些随机字节(可能使用arc4random_buf(3)),然后一点一点地从中提取。

对于 K = 2,我可以简单地将所需的位屏蔽掉,但是当 K 不是 2 的幂时,事情就会变得棘手。当然我可以使用一堆%=and /=,但是我会有模偏差。另一个问题是当 N 变得太大时,我不能再将整个缓冲区解释为整数并对其执行算术运算。

如果相关,K 将小于 20,而 N 可能非常大,例如数百万。

4

1 回答 1

3

您可以使用模运算符和除法,您只需要做一些额外的预处理。正常生成值数组。取小于或等于P的最大幂(其中表示取幂),并遍历您的数组,确保所有随机值都严格小于 then 。任何不是,替换为小于 的新随机数。这将消除偏见。K2^32^PP

现在要处理 large N,您需要两个循环。第一个循环遍历数组中的元素,第二个循环从每个元素中提取多个随机数。如果P = k ^ e,那么您可以从数组中的每个元素中提取e随机数。[0, k)每次从元素中提取随机数时,对该元素进行下限除法k

当然,这不一定是实际的循环。您可以存储两个变量(数组索引、子元素索引)并array_index在调用函数时从元素中提取。如果sub_element_index == e,则将其重置为零并增加array_index。从此数组元素中提取一个随机数并将其返回。

于 2019-03-10T08:06:25.053 回答