diff options
Diffstat (limited to 'contrib/src/boost/uuid/seed_rng.hpp')
-rw-r--r-- | contrib/src/boost/uuid/seed_rng.hpp | 642 |
1 files changed, 321 insertions, 321 deletions
diff --git a/contrib/src/boost/uuid/seed_rng.hpp b/contrib/src/boost/uuid/seed_rng.hpp index 388a8f9..cd8d4ec 100644 --- a/contrib/src/boost/uuid/seed_rng.hpp +++ b/contrib/src/boost/uuid/seed_rng.hpp @@ -1,321 +1,321 @@ -// Boost seed_rng.hpp header file ----------------------------------------------// - -// Copyright 2007 Andy Tompkins. -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// Revision History -// 09 Nov 2007 - Initial Revision -// 25 Feb 2008 - moved to namespace boost::uuids::detail -// 28 Nov 2009 - disabled deprecated warnings for MSVC -// 28 Jul 2014 - fixed valgrind warnings and better entropy sources for MSVC - -// seed_rng models a UniformRandomNumberGenerator (see Boost.Random). -// Random number generators are hard to seed well. This is intended to provide -// good seed values for random number generators. -// It creates random numbers from a sha1 hash of data from a variary of sources, -// all of which are standard function calls. It produces random numbers slowly. -// Peter Dimov provided the details of sha1_random_digest_(). -// see http://archives.free.net.ph/message/20070507.175609.4c4f503a.en.html - -#ifndef BOOST_UUID_SEED_RNG_HPP -#define BOOST_UUID_SEED_RNG_HPP - -#include <boost/config.hpp> -#include <cstring> // for memcpy -#include <limits> -#include <ctime> // for time_t, time, clock_t, clock -#include <cstdlib> // for rand -#include <cstdio> // for FILE, fopen, fread, fclose -#include <boost/core/noncopyable.hpp> -#include <boost/uuid/sha1.hpp> -//#include <boost/nondet_random.hpp> //forward declare boost::random::random_device - -// can't use boost::generator_iterator since boost::random number seed(Iter&, Iter) -// functions need a last iterator -//#include <boost/generator_iterator.hpp> -# include <boost/iterator/iterator_facade.hpp> - -#if defined(_MSC_VER) -# pragma warning(push) // Save warning settings. -# pragma warning(disable : 4996) // Disable deprecated std::fopen -#if defined(_WIN32_WCE) -# pragma comment(lib, "coredll.lib") -#else -# pragma comment(lib, "advapi32.lib") -#endif -#endif - -#if defined(BOOST_WINDOWS) -# include <boost/detail/winapi/crypt.hpp> // for CryptAcquireContextA, CryptGenRandom, CryptReleaseContext -# include <boost/detail/winapi/timers.hpp> -# include <boost/detail/winapi/get_current_process_id.hpp> -# include <boost/detail/winapi/get_current_thread_id.hpp> -#else -# include <sys/time.h> // for gettimeofday -# include <sys/types.h> // for pid_t -# include <unistd.h> // for getpid() -#endif - -#ifdef BOOST_NO_STDC_NAMESPACE -namespace std { - using ::memcpy; - using ::time_t; - using ::time; - using ::clock_t; - using ::clock; - using ::rand; - using ::FILE; - using ::fopen; - using ::fread; - using ::fclose; -} //namespace std -#endif - -// forward declare random number generators -namespace boost { namespace random { -class random_device; -}} //namespace boost::random - -namespace boost { -namespace uuids { -namespace detail { - -// should this be part of Boost.Random? -class seed_rng: private boost::noncopyable -{ -public: - typedef unsigned int result_type; - BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); - -public: - // note: rd_ intentionally left uninitialized - seed_rng() BOOST_NOEXCEPT - : rd_index_(5) - , random_(NULL) - { -#if defined(BOOST_WINDOWS) - if (!boost::detail::winapi::CryptAcquireContextW( - &random_, - NULL, - NULL, - boost::detail::winapi::PROV_RSA_FULL_, - boost::detail::winapi::CRYPT_VERIFYCONTEXT_ | boost::detail::winapi::CRYPT_SILENT_)) - { - random_ = NULL; - } -#else - random_ = std::fopen( "/dev/urandom", "rb" ); -#endif - - std::memset(rd_, 0, sizeof(rd_)); - } - - ~seed_rng() BOOST_NOEXCEPT - { - if (random_) { -#if defined(BOOST_WINDOWS) - boost::detail::winapi::CryptReleaseContext(random_, 0); -#else - std::fclose(random_); -#endif - } - } - - result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const BOOST_NOEXCEPT - { - return (std::numeric_limits<result_type>::min)(); - } - result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const BOOST_NOEXCEPT - { - return (std::numeric_limits<result_type>::max)(); - } - - result_type operator()() - { - if (rd_index_ >= 5) { - //get new digest - sha1_random_digest_(); - - rd_index_ = 0; - } - - return rd_[rd_index_++]; - } - -private: - BOOST_STATIC_CONSTANT(std::size_t, internal_state_size = 5); - inline void ignore_size(size_t) {} - - static unsigned int * sha1_random_digest_state_() - { - static unsigned int state[ internal_state_size ]; - return state; - } - - void sha1_random_digest_() - { - boost::uuids::detail::sha1 sha; - - - if (random_) - { - // intentionally left uninitialized - unsigned char state[ 20 ]; -#if defined(BOOST_WINDOWS) - boost::detail::winapi::CryptGenRandom(random_, sizeof(state), state); -#else - ignore_size(std::fread( state, 1, sizeof(state), random_ )); -#endif - sha.process_bytes( state, sizeof( state ) ); - } - - { - // Getting enropy from some system specific sources -#if defined(BOOST_WINDOWS) - boost::detail::winapi::DWORD_ procid = boost::detail::winapi::GetCurrentProcessId(); - sha.process_bytes( (unsigned char const*)&procid, sizeof( procid ) ); - - boost::detail::winapi::DWORD_ threadid = boost::detail::winapi::GetCurrentThreadId(); - sha.process_bytes( (unsigned char const*)&threadid, sizeof( threadid ) ); - - boost::detail::winapi::LARGE_INTEGER_ ts; - ts.QuadPart = 0; - boost::detail::winapi::QueryPerformanceCounter( &ts ); - sha.process_bytes( (unsigned char const*)&ts, sizeof( ts ) ); - - std::time_t tm = std::time( 0 ); - sha.process_bytes( (unsigned char const*)&tm, sizeof( tm ) ); -#else - pid_t pid = getpid(); - sha.process_bytes( (unsigned char const*)&pid, sizeof( pid ) ); - - timeval ts; - gettimeofday(&ts, NULL); // We do not use `clock_gettime` to avoid linkage with -lrt - sha.process_bytes( (unsigned char const*)&ts, sizeof( ts ) ); -#endif - } - - - unsigned int * ps = sha1_random_digest_state_(); - sha.process_bytes( ps, internal_state_size * sizeof( unsigned int ) ); - sha.process_bytes( (unsigned char const*)&ps, sizeof( ps ) ); - - { - std::clock_t ck = std::clock(); - sha.process_bytes( (unsigned char const*)&ck, sizeof( ck ) ); - } - - { - unsigned int rn[] = - { static_cast<unsigned int>(std::rand()) - , static_cast<unsigned int>(std::rand()) - , static_cast<unsigned int>(std::rand()) - }; - sha.process_bytes( (unsigned char const*)rn, sizeof( rn ) ); - } - - { - unsigned int * p = new unsigned int; - sha.process_bytes( (unsigned char const*)&p, sizeof( p ) ); - delete p; - - const seed_rng* this_ptr = this; - sha.process_bytes( (unsigned char const*)&this_ptr, sizeof( this_ptr ) ); - sha.process_bytes( (unsigned char const*)&std::rand, sizeof( void(*)() ) ); - } - - sha.process_bytes( (unsigned char const*)rd_, sizeof( rd_ ) ); - - unsigned int digest[ 5 ]; - sha.get_digest( digest ); - - for( int i = 0; i < 5; ++i ) - { - // harmless data race - ps[ i ] ^= digest[ i ]; - rd_[ i ] ^= digest[ i ]; - } - } - -private: - unsigned int rd_[5]; - int rd_index_; - -#if defined(BOOST_WINDOWS) - boost::detail::winapi::HCRYPTPROV_ random_; -#else - std::FILE * random_; -#endif -}; - -// almost a copy of boost::generator_iterator -// but default constructor sets m_g to NULL -template <class Generator> -class generator_iterator - : public iterator_facade< - generator_iterator<Generator> - , typename Generator::result_type - , single_pass_traversal_tag - , typename Generator::result_type const& - > -{ - typedef iterator_facade< - generator_iterator<Generator> - , typename Generator::result_type - , single_pass_traversal_tag - , typename Generator::result_type const& - > super_t; - - public: - generator_iterator() : m_g(NULL), m_value(0) {} - generator_iterator(Generator* g) : m_g(g), m_value((*m_g)()) {} - - void increment() - { - m_value = (*m_g)(); - } - - const typename Generator::result_type& - dereference() const - { - return m_value; - } - - bool equal(generator_iterator const& y) const - { - return this->m_g == y.m_g && this->m_value == y.m_value; - } - - private: - Generator* m_g; - typename Generator::result_type m_value; -}; - -// seed() seeds a random number generator with good seed values - -template <typename UniformRandomNumberGenerator> -inline void seed(UniformRandomNumberGenerator& rng) -{ - seed_rng seed_gen; - generator_iterator<seed_rng> begin(&seed_gen); - generator_iterator<seed_rng> end; - rng.seed(begin, end); -} - -// random_device does not / can not be seeded -template <> -inline void seed<boost::random::random_device>(boost::random::random_device&) {} - -// random_device does not / can not be seeded -template <> -inline void seed<seed_rng>(seed_rng&) {} - -}}} //namespace boost::uuids::detail - -#if defined(_MSC_VER) -#pragma warning(pop) // Restore warnings to previous state. -#endif - -#endif +// Boost seed_rng.hpp header file ----------------------------------------------//
+
+// Copyright 2007 Andy Tompkins.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Revision History
+// 09 Nov 2007 - Initial Revision
+// 25 Feb 2008 - moved to namespace boost::uuids::detail
+// 28 Nov 2009 - disabled deprecated warnings for MSVC
+// 28 Jul 2014 - fixed valgrind warnings and better entropy sources for MSVC
+
+// seed_rng models a UniformRandomNumberGenerator (see Boost.Random).
+// Random number generators are hard to seed well. This is intended to provide
+// good seed values for random number generators.
+// It creates random numbers from a sha1 hash of data from a variary of sources,
+// all of which are standard function calls. It produces random numbers slowly.
+// Peter Dimov provided the details of sha1_random_digest_().
+// see http://archives.free.net.ph/message/20070507.175609.4c4f503a.en.html
+
+#ifndef BOOST_UUID_SEED_RNG_HPP
+#define BOOST_UUID_SEED_RNG_HPP
+
+#include <boost/config.hpp>
+#include <cstring> // for memcpy
+#include <limits>
+#include <ctime> // for time_t, time, clock_t, clock
+#include <cstdlib> // for rand
+#include <cstdio> // for FILE, fopen, fread, fclose
+#include <boost/core/noncopyable.hpp>
+#include <boost/uuid/sha1.hpp>
+//#include <boost/nondet_random.hpp> //forward declare boost::random::random_device
+
+// can't use boost::generator_iterator since boost::random number seed(Iter&, Iter)
+// functions need a last iterator
+//#include <boost/generator_iterator.hpp>
+# include <boost/iterator/iterator_facade.hpp>
+
+#if defined(_MSC_VER)
+# pragma warning(push) // Save warning settings.
+# pragma warning(disable : 4996) // Disable deprecated std::fopen
+#if defined(_WIN32_WCE)
+# pragma comment(lib, "coredll.lib")
+#else
+# pragma comment(lib, "advapi32.lib")
+#endif
+#endif
+
+#if defined(BOOST_WINDOWS)
+# include <boost/detail/winapi/crypt.hpp> // for CryptAcquireContextA, CryptGenRandom, CryptReleaseContext
+# include <boost/detail/winapi/timers.hpp>
+# include <boost/detail/winapi/get_current_process_id.hpp>
+# include <boost/detail/winapi/get_current_thread_id.hpp>
+#else
+# include <sys/time.h> // for gettimeofday
+# include <sys/types.h> // for pid_t
+# include <unistd.h> // for getpid()
+#endif
+
+#ifdef BOOST_NO_STDC_NAMESPACE
+namespace std {
+ using ::memcpy;
+ using ::time_t;
+ using ::time;
+ using ::clock_t;
+ using ::clock;
+ using ::rand;
+ using ::FILE;
+ using ::fopen;
+ using ::fread;
+ using ::fclose;
+} //namespace std
+#endif
+
+// forward declare random number generators
+namespace boost { namespace random {
+class random_device;
+}} //namespace boost::random
+
+namespace boost {
+namespace uuids {
+namespace detail {
+
+// should this be part of Boost.Random?
+class seed_rng: private boost::noncopyable
+{
+public:
+ typedef unsigned int result_type;
+ BOOST_STATIC_CONSTANT(bool, has_fixed_range = false);
+
+public:
+ // note: rd_ intentionally left uninitialized
+ seed_rng() BOOST_NOEXCEPT
+ : rd_index_(5)
+ , random_(NULL)
+ {
+#if defined(BOOST_WINDOWS)
+ if (!boost::detail::winapi::CryptAcquireContextW(
+ &random_,
+ NULL,
+ NULL,
+ boost::detail::winapi::PROV_RSA_FULL_,
+ boost::detail::winapi::CRYPT_VERIFYCONTEXT_ | boost::detail::winapi::CRYPT_SILENT_))
+ {
+ random_ = NULL;
+ }
+#else
+ random_ = std::fopen( "/dev/urandom", "rb" );
+#endif
+
+ std::memset(rd_, 0, sizeof(rd_));
+ }
+
+ ~seed_rng() BOOST_NOEXCEPT
+ {
+ if (random_) {
+#if defined(BOOST_WINDOWS)
+ boost::detail::winapi::CryptReleaseContext(random_, 0);
+#else
+ std::fclose(random_);
+#endif
+ }
+ }
+
+ result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const BOOST_NOEXCEPT
+ {
+ return (std::numeric_limits<result_type>::min)();
+ }
+ result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const BOOST_NOEXCEPT
+ {
+ return (std::numeric_limits<result_type>::max)();
+ }
+
+ result_type operator()()
+ {
+ if (rd_index_ >= 5) {
+ //get new digest
+ sha1_random_digest_();
+
+ rd_index_ = 0;
+ }
+
+ return rd_[rd_index_++];
+ }
+
+private:
+ BOOST_STATIC_CONSTANT(std::size_t, internal_state_size = 5);
+ inline void ignore_size(size_t) {}
+
+ static unsigned int * sha1_random_digest_state_()
+ {
+ static unsigned int state[ internal_state_size ];
+ return state;
+ }
+
+ void sha1_random_digest_()
+ {
+ boost::uuids::detail::sha1 sha;
+
+
+ if (random_)
+ {
+ // intentionally left uninitialized
+ unsigned char state[ 20 ];
+#if defined(BOOST_WINDOWS)
+ boost::detail::winapi::CryptGenRandom(random_, sizeof(state), state);
+#else
+ ignore_size(std::fread( state, 1, sizeof(state), random_ ));
+#endif
+ sha.process_bytes( state, sizeof( state ) );
+ }
+
+ {
+ // Getting enropy from some system specific sources
+#if defined(BOOST_WINDOWS)
+ boost::detail::winapi::DWORD_ procid = boost::detail::winapi::GetCurrentProcessId();
+ sha.process_bytes( (unsigned char const*)&procid, sizeof( procid ) );
+
+ boost::detail::winapi::DWORD_ threadid = boost::detail::winapi::GetCurrentThreadId();
+ sha.process_bytes( (unsigned char const*)&threadid, sizeof( threadid ) );
+
+ boost::detail::winapi::LARGE_INTEGER_ ts;
+ ts.QuadPart = 0;
+ boost::detail::winapi::QueryPerformanceCounter( &ts );
+ sha.process_bytes( (unsigned char const*)&ts, sizeof( ts ) );
+
+ std::time_t tm = std::time( 0 );
+ sha.process_bytes( (unsigned char const*)&tm, sizeof( tm ) );
+#else
+ pid_t pid = getpid();
+ sha.process_bytes( (unsigned char const*)&pid, sizeof( pid ) );
+
+ timeval ts;
+ gettimeofday(&ts, NULL); // We do not use `clock_gettime` to avoid linkage with -lrt
+ sha.process_bytes( (unsigned char const*)&ts, sizeof( ts ) );
+#endif
+ }
+
+
+ unsigned int * ps = sha1_random_digest_state_();
+ sha.process_bytes( ps, internal_state_size * sizeof( unsigned int ) );
+ sha.process_bytes( (unsigned char const*)&ps, sizeof( ps ) );
+
+ {
+ std::clock_t ck = std::clock();
+ sha.process_bytes( (unsigned char const*)&ck, sizeof( ck ) );
+ }
+
+ {
+ unsigned int rn[] =
+ { static_cast<unsigned int>(std::rand())
+ , static_cast<unsigned int>(std::rand())
+ , static_cast<unsigned int>(std::rand())
+ };
+ sha.process_bytes( (unsigned char const*)rn, sizeof( rn ) );
+ }
+
+ {
+ unsigned int * p = new unsigned int;
+ sha.process_bytes( (unsigned char const*)&p, sizeof( p ) );
+ delete p;
+
+ const seed_rng* this_ptr = this;
+ sha.process_bytes( (unsigned char const*)&this_ptr, sizeof( this_ptr ) );
+ sha.process_bytes( (unsigned char const*)&std::rand, sizeof( void(*)() ) );
+ }
+
+ sha.process_bytes( (unsigned char const*)rd_, sizeof( rd_ ) );
+
+ unsigned int digest[ 5 ];
+ sha.get_digest( digest );
+
+ for( int i = 0; i < 5; ++i )
+ {
+ // harmless data race
+ ps[ i ] ^= digest[ i ];
+ rd_[ i ] ^= digest[ i ];
+ }
+ }
+
+private:
+ unsigned int rd_[5];
+ int rd_index_;
+
+#if defined(BOOST_WINDOWS)
+ boost::detail::winapi::HCRYPTPROV_ random_;
+#else
+ std::FILE * random_;
+#endif
+};
+
+// almost a copy of boost::generator_iterator
+// but default constructor sets m_g to NULL
+template <class Generator>
+class generator_iterator
+ : public iterator_facade<
+ generator_iterator<Generator>
+ , typename Generator::result_type
+ , single_pass_traversal_tag
+ , typename Generator::result_type const&
+ >
+{
+ typedef iterator_facade<
+ generator_iterator<Generator>
+ , typename Generator::result_type
+ , single_pass_traversal_tag
+ , typename Generator::result_type const&
+ > super_t;
+
+ public:
+ generator_iterator() : m_g(NULL), m_value(0) {}
+ generator_iterator(Generator* g) : m_g(g), m_value((*m_g)()) {}
+
+ void increment()
+ {
+ m_value = (*m_g)();
+ }
+
+ const typename Generator::result_type&
+ dereference() const
+ {
+ return m_value;
+ }
+
+ bool equal(generator_iterator const& y) const
+ {
+ return this->m_g == y.m_g && this->m_value == y.m_value;
+ }
+
+ private:
+ Generator* m_g;
+ typename Generator::result_type m_value;
+};
+
+// seed() seeds a random number generator with good seed values
+
+template <typename UniformRandomNumberGenerator>
+inline void seed(UniformRandomNumberGenerator& rng)
+{
+ seed_rng seed_gen;
+ generator_iterator<seed_rng> begin(&seed_gen);
+ generator_iterator<seed_rng> end;
+ rng.seed(begin, end);
+}
+
+// random_device does not / can not be seeded
+template <>
+inline void seed<boost::random::random_device>(boost::random::random_device&) {}
+
+// random_device does not / can not be seeded
+template <>
+inline void seed<seed_rng>(seed_rng&) {}
+
+}}} //namespace boost::uuids::detail
+
+#if defined(_MSC_VER)
+#pragma warning(pop) // Restore warnings to previous state.
+#endif
+
+#endif
|