从预先填充的随机缓冲区中提取基K随机“位”

问题描述 投票:2回答:1

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

但是,分析器告诉我,对arc4random_uniform(3)的大量调用占用了整个执行时间的2/3,而且我真的需要让代码更快。这就是我计划提前生成一些随机字节(可能使用arc4random_buf(3))并随后逐位提取的原因。

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

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

c algorithm performance random cryptography
1个回答
3
投票

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

现在要处理大型N,你需要两个循环。第一个循环遍历数组中的元素,第二个循环从每个元素中提取多个随机数。如果P = k ^ e,那么你可以从数组中的每个元素从e中提取[0, k)随机数。每次从元素中提取随机数时,都要对该元素执行k的分层。

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

© www.soinside.com 2019 - 2024. All rights reserved.