0

使用以下简单的代码片段:

struct timespec ts;
for (int i = 0; i < 100; i++) {
    timespec_get(&ts, TIME_UTC);
    printf("%ld, ", ts.tv_nsec % 100);
}

我得到这样的输出:

58, 1, 74, 49, 5, 59, 89, 20, 52, 86, 17, 48, 79, 10, 41, 73, 3, 40, 72, 3, 36, 67, 98, 30, 61, 92, 24, 55, 86, 17, 49, 82, 14, 45, 76, 7, 40, 72, 3, 36, 71, 2, 35, 66, 97, 28, 66, 97, 28, 60, 90, 22, 52, 83, 15, 46, 77, 7, 41, 72, 3, 36, 67, 0, 44, 17, 82, 13, 45, 77, 8, 59, 90, 22, 54, 85, 17, 48, 80, 12, 43, 75, 6, 57, 89, 20, 52, 84, 15, 47, 79, 14, 50, 82, 16, 47, 79, 11, 43, 74,

我没有研究数字的统计分布,我的搜索结果是空白的,但乍一看,输出确实类似于rand()or的输出random()。有没有人研究过这个或能够发表意见 - 可以timespec_get()用作随机数生成器?会不会是伪随机的?为什么?

4

3 回答 3

5

可以timespec_get()用作随机数生成器吗?

当然。但这并不意味着这样的 RNG 的输出将具有理想的甚至可以接受的统计特性。

特别是,连续的输出彼此之间具有很强的相关性。您的示例通过丢弃所有最重要的十进制数字在某种程度上隐藏了这一点。此外,系统时钟不需要具有单纳秒分辨率,尽管您的似乎有。在没有这种分辨率的系统中,所有结果的最低有效数字可能是相关的,并且它们的分布不均匀。

会不会是伪随机的?为什么?

不,实际上。PRNG 的输出对于调用程序在调用时的运行时状态 是确定性的。timespec_get()另一方面,取决于程序的执行上下文,而不是它自己的状态。

于 2020-01-16T14:36:47.863 回答
2

您提供的代码几乎可以肯定不会提供(伪)随机数!

为什么?

考虑在一个高效的 CPU 上运行它,它可以将 100% 的时间用于您的代码(并且没有其他任何“重大影响”)在操作系统后台进行:for循环的每次运行都执行相同的指令序列,因此间隔连续调用之间timespec_get非常相似 - 具有连续相似间隔的数字列表当然不是随机的。

即使对生成的数字列表进行相当粗略的一瞥,也会显示一个数字小于其前体的唯一时间是值“翻转”到 100 标记时(如果您将模数从100增加到 ,这种效果会更加明显,例如,500并再次运行测试)。

于 2020-01-16T14:36:37.240 回答
2

timespec_get() 可以用作随机数生成器吗?

我尝试多次调用timespec_get(&ts, TIME_UTC);并收到大约 14 +/- 1 ns 的增量值。对我来说,这最多意味着每次调用 1 位的不可预测性(随机性)(考虑到增量的可变性),而不是 7 到 8 位希望的timespec_get(&ts, TIME_UTC); ts.tv_nsec % 100. 在最坏的情况下,随机性几乎为零。

.tv_nsec并且.tv_sec可以用于初始化随机引擎,但作为源,它非常弱。

会不会是伪随机的?为什么?

不,PRNG是确定性的。阅读时间不够确定。

于 2020-01-16T19:27:30.627 回答