用随机数据填充内存区域
Populate a region of memory with random data
我正在尝试使用 rand
跨平台以一种有效的方式随机填充数据区域。这是我目前所拥有的:
/**********************************************\
* Useful macro by Glen Ragen *
* *
\**********************************************/
#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
应该能够优化为调用时间常量,而不是在 for 循环的每次迭代中都进行评估。
但是,位操作很慢,fill_data_with_randomness
函数会被调用的很频繁。此函数应在具有 2^n-1 形式的任何 RAND_MAX
值的系统上正确编译 运行。什么 fill_data_with_randomness
函数可以快速地用 rand()
mness 填充这个内存区域而不浪费位?
RAND_MAX
保证至少为 215−1 因此通过一次调用 [=11= 随机填充整个字节是没有问题的],除非你的架构有大于 15 位的字节(在这种情况下,你的硬编码乘以 8 也会有问题)。
逐字节进行生成非常简单,不需要位黑客技巧。
就我个人而言,我不会担心 "wasting bits" 来自对 rand()
的调用;该标准库函数生成的位在大多数实现中价值不大。真正的问题是决定丢弃哪些位,以便剩余的位合理分布。如果可能的话,为了应对通常使用的劣质 PRNG 的范围,您应该选择中间位。
更好的解决方案可能是简单地提供您自己的 PRNG;存在可移植的源代码实现,其中一些已得到很好的研究。
我正在尝试使用 rand
跨平台以一种有效的方式随机填充数据区域。这是我目前所拥有的:
/**********************************************\
* Useful macro by Glen Ragen *
* *
\**********************************************/
#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
应该能够优化为调用时间常量,而不是在 for 循环的每次迭代中都进行评估。
但是,位操作很慢,fill_data_with_randomness
函数会被调用的很频繁。此函数应在具有 2^n-1 形式的任何 RAND_MAX
值的系统上正确编译 运行。什么 fill_data_with_randomness
函数可以快速地用 rand()
mness 填充这个内存区域而不浪费位?
RAND_MAX
保证至少为 215−1 因此通过一次调用 [=11= 随机填充整个字节是没有问题的],除非你的架构有大于 15 位的字节(在这种情况下,你的硬编码乘以 8 也会有问题)。
逐字节进行生成非常简单,不需要位黑客技巧。
就我个人而言,我不会担心 "wasting bits" 来自对 rand()
的调用;该标准库函数生成的位在大多数实现中价值不大。真正的问题是决定丢弃哪些位,以便剩余的位合理分布。如果可能的话,为了应对通常使用的劣质 PRNG 的范围,您应该选择中间位。
更好的解决方案可能是简单地提供您自己的 PRNG;存在可移植的源代码实现,其中一些已得到很好的研究。