You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

52 lines
1.5 KiB

  1. /* udns_jran.c: small non-cryptographic random number generator
  2. * taken from http://burtleburtle.net/bob/rand/smallprng.html
  3. * by Bob Jenkins, Public domain.
  4. */
  5. #include "udns.h"
  6. #define rot32(x,k) (((x) << (k)) | ((x) >> (32-(k))))
  7. #define rot64(x,k) (((x) << (k)) | ((x) >> (64-(k))))
  8. #define tr32(x) ((x)&0xffffffffu)
  9. unsigned udns_jranval(struct udns_jranctx *x) {
  10. /* This routine can be made to work with either 32 or 64bit words -
  11. * if JRAN_32_64 is defined when compiling the file.
  12. * We use if() instead of #if since there's no good
  13. * portable way to check sizeof() in preprocessor without
  14. * introducing some ugly configure-time checks.
  15. * Most compilers will optimize the wrong branches away anyway.
  16. * By default it assumes 32bit integers
  17. */
  18. #ifdef JRAN_32_64
  19. if (sizeof(unsigned) == 4) {
  20. #endif
  21. unsigned e = tr32(x->a - rot32(x->b, 27));
  22. x->a = tr32(x->b ^ rot32(x->c, 17));
  23. x->b = tr32(x->c + x->d);
  24. x->c = tr32(x->d + e);
  25. x->d = tr32(e + x->a);
  26. #ifdef JRAN_32_64
  27. }
  28. else if (sizeof(unsigned) == 8) { /* assuming it's 64bits */
  29. unsigned e = x->a - rot64(x->b, 7);
  30. x->a = x->b ^ rot64(x->c, 13);
  31. x->b = x->c + rot64(x->d, 37);
  32. x->c = x->d + e;
  33. x->d = e + x->a;
  34. }
  35. else {
  36. unsigned e = 0;
  37. x->d = 1/e; /* bail */
  38. }
  39. #endif
  40. return x->d;
  41. }
  42. void udns_jraninit(struct udns_jranctx *x, unsigned seed) {
  43. unsigned i;
  44. x->a = 0xf1ea5eed;
  45. x->b = x->c = x->d = seed;
  46. for (i = 0; i < 20; ++i)
  47. (void)udns_jranval(x);
  48. }