使用 "timespec_get()" 在 Linux 上返回的 "tv_nsec" 纳秒分量作为 C 中的随机数生成器的可行性?
Viability of using the "tv_nsec" nanosecond component returned by "timespec_get()" on Linux as random number generator in C?
使用以下简单的代码片段:
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()
或 random()
的输出。有没有人研究过这个或者能够表达意见 - timespec_get()
可以用作随机数生成器吗?它会不会是伪随机的?为什么?
您提供的代码几乎可以保证不会提供(伪)随机数!
为什么?
考虑 运行在一个高效的 CPU 上进行此操作,它可以将 100% 的时间用于您的代码(没有其他 'significant impact')在 OS 背景:for
循环的每个 运行 执行一个 相同的 指令序列,因此对 timespec_get
的连续调用之间的间隔都是非常相似 - 具有连续相似间隔的数字列表肯定不是随机的。
即使粗略地浏览一下您生成的数字列表也会发现,只有当值 "rolls over" 为 100 标记(如果您将模数从 100
增加到例如 500
和 运行 再次测试,这种效果会更加明显。
could timespec_get()
be used as random number generator?
当然可以。但这并不意味着这样的 RNG 的输出将具有理想甚至可接受的统计属性。
特别是,连续的输出彼此密切相关。您的示例通过丢弃所有最重要的十进制数字在某种程度上隐藏了这一点。此外,系统时钟不需要具有单纳秒分辨率,尽管您的时钟似乎具有。在没有这种分辨率的系统中,所有结果的最低有效数字可能是相关的,并且它们的分布不均匀。
Would it be pseudo random or not? Why?
不,实际上。 PRNG 的输出相对于调用程序在调用时的运行时状态是 确定性的 。 timespec_get()
,另一方面,取决于程序的执行上下文,而不是它自己的状态。
could timespec_get() be used as random number generator?
我尝试多次调用 timespec_get(&ts, TIME_UTC);
并收到大约 14 +/- 1 ns 的增量值。对我来说,这意味着 充其量 每次调用 1 位的不可预测性(随机性)(考虑到增量的可变性),而不是希望的 7 到 8 位timespec_get(&ts, TIME_UTC); ts.tv_nsec % 100
。 在最坏的情况下,随机性几乎为零。
.tv_nsec
和 .tv_sec
可以用于 随机引擎,但作为来源,它非常弱。
Would it be pseudo random or not? Why?
没有。 PRNG 是确定性的。阅读时间不够确定。
使用以下简单的代码片段:
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()
或 random()
的输出。有没有人研究过这个或者能够表达意见 - timespec_get()
可以用作随机数生成器吗?它会不会是伪随机的?为什么?
您提供的代码几乎可以保证不会提供(伪)随机数!
为什么?
考虑 运行在一个高效的 CPU 上进行此操作,它可以将 100% 的时间用于您的代码(没有其他 'significant impact')在 OS 背景:for
循环的每个 运行 执行一个 相同的 指令序列,因此对 timespec_get
的连续调用之间的间隔都是非常相似 - 具有连续相似间隔的数字列表肯定不是随机的。
即使粗略地浏览一下您生成的数字列表也会发现,只有当值 "rolls over" 为 100 标记(如果您将模数从 100
增加到例如 500
和 运行 再次测试,这种效果会更加明显。
could
timespec_get()
be used as random number generator?
当然可以。但这并不意味着这样的 RNG 的输出将具有理想甚至可接受的统计属性。
特别是,连续的输出彼此密切相关。您的示例通过丢弃所有最重要的十进制数字在某种程度上隐藏了这一点。此外,系统时钟不需要具有单纳秒分辨率,尽管您的时钟似乎具有。在没有这种分辨率的系统中,所有结果的最低有效数字可能是相关的,并且它们的分布不均匀。
Would it be pseudo random or not? Why?
不,实际上。 PRNG 的输出相对于调用程序在调用时的运行时状态是 确定性的 。 timespec_get()
,另一方面,取决于程序的执行上下文,而不是它自己的状态。
could timespec_get() be used as random number generator?
我尝试多次调用 timespec_get(&ts, TIME_UTC);
并收到大约 14 +/- 1 ns 的增量值。对我来说,这意味着 充其量 每次调用 1 位的不可预测性(随机性)(考虑到增量的可变性),而不是希望的 7 到 8 位timespec_get(&ts, TIME_UTC); ts.tv_nsec % 100
。 在最坏的情况下,随机性几乎为零。
.tv_nsec
和 .tv_sec
可以用于
Would it be pseudo random or not? Why?
没有。 PRNG 是确定性的。阅读时间不够确定。