简体   繁体   English

rand() function 总是用相同的种子产生相同的结果吗?

[英]Will the rand() function ALWAYS produce the same result with the same seed?

I am trying to implement a set of encode and decode steganography functions in C , where i use rand() to randomly scatter my data along an array.我正在尝试在C中实现一组编码和解码隐写功能,其中我使用 rand() 沿数组随机分散我的数据。

I use rand to calculate a random index like so:我使用 rand 来计算随机索引,如下所示:

unsigned int getRandIndex(int size) {
  return ((unsigned)(rand() * 8)) % size;
}

I seed rand like so:我像这样播种兰特:

unsigned long seed = time(NULL);
srand(seed);

I include the seed along with my data as a part of a header that contains a checksum and length.我将种子与我的数据一起作为包含校验和和长度的 header 的一部分。

The problem i have is that while decoding, when i seed the rand function again with the seed i decoded from the data, rand() tends to produce the slightest variations like so:我遇到的问题是,在解码时,当我用从数据中解码的种子再次播种 rand function 时,rand() 往往会产生最轻微的变化,如下所示:

Index at encode:                  | Index at decode:
---------------------------------------------------------------------
.
.
.
At:                        142568 | At:                        142568
At:                        155560 | At:                        155552
                               --                                  --
At:                        168184 | At:                        168184
.
.
.

Messing up my decoded data.弄乱我的解码数据。

Is this a limitation of the rand() function?这是 rand() function 的限制吗? I am 100% sure that the seed is being decoded correctly bit-for-bit as i have verified that.正如我已经验证的那样,我 100% 确定种子正在逐位正确解码。

C 2018 7.22.2.2 2 says: C 2018 7.22.2.2 2 说:

The srand function uses the argument as a seed for a new sequence of pseudo-random numbers to be returned by subsequent calls to rand . srand function 使用该参数作为后续调用rand将返回的新伪随机数序列的种子。 If srand is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated.如果随后使用相同的种子值调用srand ,则应重复伪随机数序列。

This does not explicitly say the sequence is the same in different executions of the program, but I take that as understood.这并没有明确说明在程序的不同执行中顺序是相同的,但我认为这是可以理解的。 It does not, however, extend to different C implementations, including those that result from linking in a different version of the C standard library.但是,它不会扩展到不同的 C 实现,包括在不同版本的 C 标准库中链接所产生的实现。

OpenBSD's implementation of rand ignores all calls to srand and instead provides automatically seeded, cryptographically strong random numbers as if you were using arc4random ; OpenBSD 的rand实现忽略了对srand的所有调用,而是提供自动播种的、加密的强随机数,就像您使用arc4random this is documented as an intentional deviation from the C standard.这被记录为故意偏离 C 标准。 This demonstrates that even if your files are always decoded on the exact same computer that produced them, there's no guarantee rand will do what you want.这表明即使您的文件总是在生成它们的同一台计算机上解码,也不能保证rand会做您想要的。

If you need reproducible sequences of pseudorandom numbers, you should do what industrial grade statistics software does, which is ship your own PRNG and document your choice of algorithm.如果您需要可重复的伪随机数序列,您应该做工业级统计软件所做的事情,即发布您自己的 PRNG 并记录您选择的算法。 (See for instance the ?Random help page for R .) (例如参见R 的?Random帮助页面。)

Also, since this is a steganography application, you need to use a cryptographically strong PRNG (also known as a stream cipher );此外,由于这是一个隐写应用程序,您需要使用加密强PRNG(也称为stream 密码); merely statistically strong PRNGs like the Mersenne Twister are not good enough.仅仅像 Mersenne Twister 这样统计上强大的 PRNG 还不够好。

No. For reproducibility using rand (which is not exactly specified and inherently uses global state) is terrible for multiple reasons:不。对于使用rand的可重复性(未完全指定并且固有地使用全局状态)是可怕的,原因有很多:

  1. you might use a different compiler/system, which may use a different RNG,您可能使用不同的编译器/系统,它可能使用不同的 RNG,

  2. you might use the same compiler, but updated to a new version, which uses a different RNG,您可能使用相同的编译器,但更新到使用不同 RNG 的新版本,

  3. you might use the same compiler, same version, but with an updated libc , that uses a different RNG,您可能使用相同的编译器,相同的版本,但使用更新的libc ,使用不同的 RNG,

  4. you use the same compiler and library version, but have any other non-deterministic call order of the RNG, including but not limited to:您使用相同的编译器和库版本,但具有任何其他不确定的 RNG 调用顺序,包括但不限于:

    a) some other source of randomness, a) 其他一些随机性来源,

    b) user input, b) 用户输入,

    c) reordering of concurrency from run-to-run, or c) 从运行到运行重新排序并发,或

    d) any of the above in any of the libraries that you use. d) 您使用的任何库中的上述任何内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM