isaac64.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #if !defined(_isaac64_H)
  2. # define _isaac64_H (1)
  3. # include <stdint.h>
  4. typedef struct isaac64_ctx isaac64_ctx;
  5. #define ISAAC64_SZ_LOG (8)
  6. #define ISAAC64_SZ (1<<ISAAC64_SZ_LOG)
  7. #define ISAAC64_SEED_SZ_MAX (ISAAC64_SZ<<3)
  8. /*ISAAC is the most advanced of a series of pseudo-random number generators
  9. designed by Robert J. Jenkins Jr. in 1996.
  10. http://www.burtleburtle.net/bob/rand/isaac.html
  11. This is the 64-bit version.
  12. To quote:
  13. ISAAC-64 generates a different sequence than ISAAC, but it uses the same
  14. principles.
  15. It uses 64-bit arithmetic.
  16. It generates a 64-bit result every 19 instructions.
  17. All cycles are at least 2**72 values, and the average cycle length is
  18. 2**16583.*/
  19. struct isaac64_ctx{
  20. unsigned n;
  21. uint64_t r[ISAAC64_SZ];
  22. uint64_t m[ISAAC64_SZ];
  23. uint64_t a;
  24. uint64_t b;
  25. uint64_t c;
  26. };
  27. /**
  28. * isaac64_init - Initialize an instance of the ISAAC64 random number generator.
  29. * @_ctx: The ISAAC64 instance to initialize.
  30. * @_seed: The specified seed bytes.
  31. * This may be NULL if _nseed is less than or equal to zero.
  32. * @_nseed: The number of bytes to use for the seed.
  33. * If this is greater than ISAAC64_SEED_SZ_MAX, the extra bytes are
  34. * ignored.
  35. */
  36. void isaac64_init(isaac64_ctx *_ctx,const unsigned char *_seed,int _nseed);
  37. /**
  38. * isaac64_reseed - Mix a new batch of entropy into the current state.
  39. * To reset ISAAC64 to a known state, call isaac64_init() again instead.
  40. * @_ctx: The instance to reseed.
  41. * @_seed: The specified seed bytes.
  42. * This may be NULL if _nseed is zero.
  43. * @_nseed: The number of bytes to use for the seed.
  44. * If this is greater than ISAAC64_SEED_SZ_MAX, the extra bytes are
  45. * ignored.
  46. */
  47. void isaac64_reseed(isaac64_ctx *_ctx,const unsigned char *_seed,int _nseed);
  48. /**
  49. * isaac64_next_uint64 - Return the next random 64-bit value.
  50. * @_ctx: The ISAAC64 instance to generate the value with.
  51. */
  52. uint64_t isaac64_next_uint64(isaac64_ctx *_ctx);
  53. /**
  54. * isaac64_next_uint - Uniform random integer less than the given value.
  55. * @_ctx: The ISAAC64 instance to generate the value with.
  56. * @_n: The upper bound on the range of numbers returned (not inclusive).
  57. * This must be greater than zero and less than 2**64.
  58. * To return integers in the full range 0...2**64-1, use
  59. * isaac64_next_uint64() instead.
  60. * Return: An integer uniformly distributed between 0 and _n-1 (inclusive).
  61. */
  62. uint64_t isaac64_next_uint(isaac64_ctx *_ctx,uint64_t _n);
  63. /**
  64. * isaac64_next_float - Uniform random float in the range [0,1).
  65. * @_ctx: The ISAAC64 instance to generate the value with.
  66. * Returns a high-quality float uniformly distributed between 0 (inclusive)
  67. * and 1 (exclusive).
  68. * All of the float's mantissa bits are random, e.g., the least significant bit
  69. * may still be non-zero even if the value is less than 0.5, and any
  70. * representable float in the range [0,1) has a chance to be returned, though
  71. * values very close to zero become increasingly unlikely.
  72. * To generate cheaper float values that do not have these properties, use
  73. * ldexpf((float)isaac64_next_uint64(_ctx),-64);
  74. */
  75. float isaac64_next_float(isaac64_ctx *_ctx);
  76. /**
  77. * isaac64_next_signed_float - Uniform random float in the range (-1,1).
  78. * @_ctx: The ISAAC64 instance to generate the value with.
  79. * Returns a high-quality float uniformly distributed between -1 and 1
  80. * (exclusive).
  81. * All of the float's mantissa bits are random, e.g., the least significant bit
  82. * may still be non-zero even if the magnitude is less than 0.5, and any
  83. * representable float in the range (-1,1) has a chance to be returned, though
  84. * values very close to zero become increasingly unlikely.
  85. * To generate cheaper float values that do not have these properties, use
  86. * ldexpf((float)isaac64_next_uint64(_ctx),-63)-1;
  87. * though this returns values in the range [-1,1).
  88. */
  89. float isaac64_next_signed_float(isaac64_ctx *_ctx);
  90. /**
  91. * isaac64_next_double - Uniform random double in the range [0,1).
  92. * @_ctx: The ISAAC64 instance to generate the value with.
  93. * Returns a high-quality double uniformly distributed between 0 (inclusive)
  94. * and 1 (exclusive).
  95. * All of the double's mantissa bits are random, e.g., the least significant
  96. * bit may still be non-zero even if the value is less than 0.5, and any
  97. * representable double in the range [0,1) has a chance to be returned, though
  98. * values very close to zero become increasingly unlikely.
  99. * To generate cheaper double values that do not have these properties, use
  100. * ldexp((double)isaac64_next_uint64(_ctx),-64);
  101. */
  102. double isaac64_next_double(isaac64_ctx *_ctx);
  103. /**
  104. * isaac64_next_signed_double - Uniform random double in the range (-1,1).
  105. * @_ctx: The ISAAC64 instance to generate the value with.
  106. * Returns a high-quality double uniformly distributed between -1 and 1
  107. * (exclusive).
  108. * All of the double's mantissa bits are random, e.g., the least significant
  109. * bit may still be non-zero even if the value is less than 0.5, and any
  110. * representable double in the range (-1,1) has a chance to be returned,
  111. * though values very close to zero become increasingly unlikely.
  112. * To generate cheaper double values that do not have these properties, use
  113. * ldexp((double)isaac64_next_uint64(_ctx),-63)-1;
  114. * though this returns values in the range [-1,1).
  115. */
  116. double isaac64_next_signed_double(isaac64_ctx *_ctx);
  117. #endif