random.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. // Copyright (C) 2004-2021 Artifex Software, Inc.
  2. //
  3. // This file is part of MuPDF.
  4. //
  5. // MuPDF is free software: you can redistribute it and/or modify it under the
  6. // terms of the GNU Affero General Public License as published by the Free
  7. // Software Foundation, either version 3 of the License, or (at your option)
  8. // any later version.
  9. //
  10. // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. // details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
  17. //
  18. // Alternative licensing terms are available from the licensor.
  19. // For commercial licensing, see <https://www.artifex.com/> or contact
  20. // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  21. // CA 94129, USA, for further information.
  22. #include "mupdf/fitz.h"
  23. /* The pseudo-random number generator in this file is based on the MIT licensed
  24. * implementation in musl libc. */
  25. #include <string.h>
  26. /* The seed is initialized in context.c as follows:
  27. * static uint16_t __seed48[7] = { 0, 0, 0, 0xe66d, 0xdeec, 0x5, 0xb };
  28. */
  29. static uint64_t fz_rand48_step(uint16_t *xi, uint16_t *lc)
  30. {
  31. uint64_t a, x;
  32. x = xi[0] | (xi[1]+0U)<<16 | (xi[2]+0ULL)<<32;
  33. a = lc[0] | (lc[1]+0U)<<16 | (lc[2]+0ULL)<<32;
  34. x = a*x + lc[3];
  35. xi[0] = x;
  36. xi[1] = x>>16;
  37. xi[2] = x>>32;
  38. return x & 0xffffffffffffull;
  39. }
  40. double fz_erand48(fz_context *ctx, uint16_t s[3])
  41. {
  42. union {
  43. uint64_t u;
  44. double f;
  45. } x = { 0x3ff0000000000000ULL | fz_rand48_step(s, ctx->seed48+3)<<4 };
  46. return x.f - 1.0;
  47. }
  48. /*
  49. Pseudo-random numbers using a linear congruential algorithm and 48-bit
  50. integer arithmetic.
  51. */
  52. double fz_drand48(fz_context *ctx)
  53. {
  54. return fz_erand48(ctx, ctx->seed48);
  55. }
  56. int32_t fz_nrand48(fz_context *ctx, uint16_t s[3])
  57. {
  58. return fz_rand48_step(s, ctx->seed48+3) >> 17;
  59. }
  60. int32_t fz_lrand48(fz_context *ctx)
  61. {
  62. return fz_nrand48(ctx, ctx->seed48);
  63. }
  64. int32_t fz_jrand48(fz_context *ctx, uint16_t s[3])
  65. {
  66. return (int32_t)(fz_rand48_step(s, ctx->seed48+3) >> 16);
  67. }
  68. int32_t fz_mrand48(fz_context *ctx)
  69. {
  70. return fz_jrand48(ctx, ctx->seed48);
  71. }
  72. void fz_lcong48(fz_context *ctx, uint16_t p[7])
  73. {
  74. memcpy(ctx->seed48, p, sizeof ctx->seed48);
  75. }
  76. uint16_t *fz_seed48(fz_context *ctx, uint16_t *s)
  77. {
  78. static uint16_t p[3];
  79. memcpy(p, ctx->seed48, sizeof p);
  80. memcpy(ctx->seed48, s, sizeof p);
  81. return p;
  82. }
  83. void fz_srand48(fz_context *ctx, int32_t seed)
  84. {
  85. uint16_t p[3] = { 0x330e, seed, seed>>16 };
  86. fz_seed48(ctx, p);
  87. }
  88. void fz_memrnd(fz_context *ctx, unsigned char *data, int len)
  89. {
  90. #ifdef CLUSTER
  91. memset(data, 0x55, len);
  92. #else
  93. while (len-- > 0)
  94. *data++ = (unsigned char)fz_lrand48(ctx);
  95. #endif
  96. }