我试图以有效的方式使用rand
跨平台以随机方式填充数据区域。以下是我到目前为止的情况:
/**********************************************\
* Useful macro by Glen Ragen *
* https://stackoverflow.com/a/39920811/5223757 *
\**********************************************/
#if 1 /* So that the IDE minifies it */
#define NEEDS_BIT(N, B) (((unsigned long)N >> B) > 0)
#define BITS_TO_REPRESENT(N) \
(NEEDS_BIT(N, 0) + NEEDS_BIT(N, 1) + \
NEEDS_BIT(N, 2) + NEEDS_BIT(N, 3) + \
...
NEEDS_BIT(N, 60) + NEEDS_BIT(N, 61) + \
NEEDS_BIT(N, 62) + NEEDS_BIT(N, 63) \
)
#endif /* So that the IDE minifies it */
typedef struct {
size_t size; /* Size in bytes */
void *pointer;
} data;
void fill_data_with_randomness(const data data) {
for (size_t biti = 0; biti < data.size * 8; biti += BITS_TO_REPRESENT(RAND_MAX)) {
/* Fill data.pointer with bits from rand() */
}
}
由于RAND_MAX
是编译时常量,BITS_TO_REPRESENT(RAND_MAX)
也应该是。data
。由于const data
的类型为data.size * 8
,fill_data_with_randomness
应该能够优化为调用时常量,而不是在for循环的每次迭代中进行评估。
但是,位操作非常慢,RAND_MAX
函数将被频繁调用。此函数应在具有格式为2 ^ n-1的fill_data_with_randomness
的任何值的系统上进行编译和正确运行。什么rand()
函数可以用{{1}} mness快速填充这个内存区域而不浪费位?
答案 0 :(得分:4)
rand()
保证至少为2 15 -1,因此只需一次调用rand()
就可以通过随机性填充整个字节,除非你的体系结构具有大于15位的字节(在这种情况下,您的硬编码乘以8也会有问题)。
逐字节地进行生成是直截了当的,并且不需要钻头聪明。
就我个人而言,我不会担心会浪费比特&#34;致电git log --max-count=1 --pretty=format:'%H' COMMITKEY~1 -- path/to/file
;在大多数实现中,由该标准库函数产生的位并不值得。真正的问题是决定丢弃哪些比特,以便剩下的比特分配得相当好。如果可能的话,为了应对通常使用的劣质PRNG的范围,你应该选择中间位。
更好的解决方案可能是简单地提供您自己的PRNG;存在可移植的源代码实现,并且一些已被很好地研究。