bob_jenkins_rng.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright 2010 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Glorified C++ version of Bob Jenkins' random number generator.
  15. // See http://burtleburtle.net/bob/rand/smallprng.html for more details.
  16. #ifndef CRCUTIL_BOB_JENKINS_RNG_H_
  17. #define CRCUTIL_BOB_JENKINS_RNG_H_
  18. #include "base_types.h"
  19. #if !defined(_MSC_VER)
  20. #define _rotl(value, bits) \
  21. static_cast<uint32>(((value) << (bits)) + ((value) >> (32 - (bits))))
  22. #define _rotl64(value, bits) \
  23. static_cast<uint64>(((value) << (bits)) + ((value) >> (64 - (bits))))
  24. #endif // !defined(_MSC_VER)
  25. namespace crcutil {
  26. #pragma pack(push, 8)
  27. template<typename T> class BobJenkinsRng;
  28. template<> class BobJenkinsRng<uint32> {
  29. public:
  30. typedef uint32 value;
  31. value Get() {
  32. value e = a_ - _rotl(b_, 23);
  33. a_ = b_ ^ _rotl(c_, 16);
  34. b_ = c_ + _rotl(d_, 11);
  35. c_ = d_ + e;
  36. d_ = e + a_;
  37. return (d_);
  38. }
  39. void Init(value seed) {
  40. a_ = 0xf1ea5eed;
  41. b_ = seed;
  42. c_ = seed;
  43. d_ = seed;
  44. for (size_t i = 0; i < 20; ++i) {
  45. (void) Get();
  46. }
  47. }
  48. explicit BobJenkinsRng(value seed) {
  49. Init(seed);
  50. }
  51. BobJenkinsRng() {
  52. Init(0x1234567);
  53. }
  54. private:
  55. value a_;
  56. value b_;
  57. value c_;
  58. value d_;
  59. };
  60. #if HAVE_UINT64
  61. template<> class BobJenkinsRng<uint64> {
  62. public:
  63. typedef uint64 value;
  64. value Get() {
  65. value e = a_ - _rotl64(b_, 7);
  66. a_ = b_ ^ _rotl64(c_, 13);
  67. b_ = c_ + _rotl64(d_, 37);
  68. c_ = d_ + e;
  69. d_ = e + a_;
  70. return d_;
  71. }
  72. void Init(value seed) {
  73. a_ = 0xf1ea5eed;
  74. b_ = seed;
  75. c_ = seed;
  76. d_ = seed;
  77. for (size_t i = 0; i < 20; ++i) {
  78. (void) Get();
  79. }
  80. }
  81. explicit BobJenkinsRng(value seed) {
  82. Init(seed);
  83. }
  84. BobJenkinsRng() {
  85. Init(0x1234567);
  86. }
  87. private:
  88. value a_;
  89. value b_;
  90. value c_;
  91. value d_;
  92. };
  93. #endif // HAVE_UINT64
  94. #if !defined(_MSC_VER)
  95. #undef _rotl
  96. #undef _rotl64
  97. #endif // !defined(_MSC_VER)
  98. #pragma pack(pop)
  99. } // namespace crcutil
  100. #endif // CRCUTIL_BOB_JENKINS_RNG_H_