Ger*_*ang 5 c random concurrency
我是 C 编程新手,我读到 erand48() 是线程安全随机数生成的一个不错的选择。然而,该函数采用的种子值为:unsigned Short int array[3]
关于这个种子值应该初始化为什么有什么建议吗?
好吧。首先,让我明确一点,PRNG 是libc确定性的(这就是它需要种子的原因),使用 LCG -这意味着一旦有一些值就很容易预测所有值,因此是不安全的。
接着。从伪随机实数的均匀分布中erand48()返回大小的随机浮点值。double它本身不需要种子值,而是需要您提供状态缓冲区。以下是完整的声明:
double erand48(unsigned short xsubi[3]);
Run Code Online (Sandbox Code Playgroud)
有趣的是,状态缓冲区必须以随机值作为种子才能使生成器工作。我的第一个想法是阅读/dev/urandom。
我们可以用这样的方法来做到这一点(使用无缓冲读取来防止这种小读取造成的浪费):
#include <stdio.h>
#include <stdlib.h>
void *thread_f (void *i) {
// setup unbuffered urandom
urandom = fopen ("/dev/urandom", "r");
setvbuf (urandom, NULL, _IONBF, 0); // turn off buffering
// setup state buffer
unsigned short randstate[3];
// fgetc() returns a `char`, we need to fill a `short`
randstate[0] = (fgetc (urandom) << 8) | fgetc (urandom);
randstate[1] = (fgetc (urandom) << 8) | fgetc (urandom);
randstate[2] = (fgetc (urandom) << 8) | fgetc (urandom);
// cleanup urandom
fclose (urandom);
// you can now use erand48 (randstate);
... // do whatever work you need to do
return result;
}
Run Code Online (Sandbox Code Playgroud)
这是线程安全的,甚至可以确保所有线程的种子值相对安全。
当然,如果速度不是太大的问题(即:您可以忍受速度的小损失)并且您可以接受整数,那么直接进行无缓冲读取/dev/urandom是一个完美的解决方案。更好的是,/dev/urandom 提供安全、不可预测的伪随机整数(从技术上讲,是字节流,但只要匹配大小,它们就始终以整数形式工作),这些整数通常也是均匀分布的。
另外,/dev/urandom定期将熵注入其中并刷新,确保您拥有足够的相当随机的数字。
| 归档时间: |
|
| 查看次数: |
2155 次 |
| 最近记录: |