random.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include "test_helpers.h"
  4. /* The output of these tests are checked against that from musl. Other
  5. * algorithms may yield different results and still comply with the
  6. * POSIX requirements. */
  7. int main(void) {
  8. /* Should be enough to exercise the rollover branching in random()
  9. * for all possible state array sizes (up to 256 bytes, i.e. 64
  10. * 32-bit values). */
  11. size_t test_seq_len = 70;
  12. long random_result;
  13. // Should give same result as with seed 1
  14. puts("Uninitialized:");
  15. for (size_t i = 0; i < test_seq_len; i++) {
  16. random_result = random();
  17. printf("%ld\n", random_result);
  18. }
  19. puts("\nSeed 1:");
  20. srandom(1);
  21. for (size_t i = 0; i < test_seq_len; i++) {
  22. random_result = random();
  23. printf("%ld\n", random_result);
  24. }
  25. puts("\nSeed 1337:");
  26. srandom(1337);
  27. for (size_t i = 0; i < test_seq_len; i++) {
  28. random_result = random();
  29. printf("%ld\n", random_result);
  30. }
  31. /* 256 bytes (as below) is the largest possible amount of state
  32. * data. Created as a uint32_t to avoid possible alignment issues
  33. * with char. */
  34. uint32_t new_state[64] = {
  35. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  36. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  37. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  38. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  39. };
  40. unsigned int seed = 42;
  41. // Should exercise the different branches in initstate()
  42. size_t sizes[] = {8, 31, 32, 63, 64, 127, 128, 255, 256};
  43. for (size_t j = 0; j < sizeof(sizes)/sizeof(size_t); j++) {
  44. size_t size = sizes[j];
  45. printf("\nSeed %d, size %ld:\n", seed, size);
  46. initstate(seed, (char *)new_state, size);
  47. for (size_t i = 0; i < test_seq_len; i++) {
  48. random_result = random();
  49. printf("%ld\n", random_result);
  50. }
  51. }
  52. /* Test that setstate() allows the use of a different state array,
  53. * and that it correctly returns the old value. */
  54. uint32_t other_new_state[64] = {
  55. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  56. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  57. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  58. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  59. };
  60. initstate(seed, (char *)other_new_state, 32);
  61. printf("\nSeed %d, other state array:\n", seed);
  62. for (size_t i = 0; i < test_seq_len; i++) {
  63. random_result = random();
  64. printf("%ld\n", random_result);
  65. }
  66. char *should_be_other_new_state_ptr = setstate((char *)new_state);
  67. if (should_be_other_new_state_ptr == (char *)other_new_state) {
  68. puts("\nState data pointer restored correctly by setstate().");
  69. }
  70. else {
  71. puts("\nState data pointer NOT restored correctly by setstate().");
  72. }
  73. printf("\nSeed %d, back to first state array:\n", seed);
  74. for (size_t i = 0; i < test_seq_len; i++) {
  75. random_result = random();
  76. printf("%ld\n", random_result);
  77. }
  78. // Should yield NULL
  79. char *state_with_size_less_than_8 = initstate(seed, (char *)new_state, 7);
  80. printf("\nPointer returned by initstate with size < 8: %p\n",
  81. state_with_size_less_than_8);
  82. return 0;
  83. }