summaryrefslogtreecommitdiff
path: root/boost/uuid/detail/seed_rng.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/uuid/detail/seed_rng.hpp')
-rw-r--r--boost/uuid/detail/seed_rng.hpp320
1 files changed, 0 insertions, 320 deletions
diff --git a/boost/uuid/detail/seed_rng.hpp b/boost/uuid/detail/seed_rng.hpp
deleted file mode 100644
index 6b7f7808db..0000000000
--- a/boost/uuid/detail/seed_rng.hpp
+++ /dev/null
@@ -1,320 +0,0 @@
-// 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/detail/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/winapi/crypt.hpp> // for CryptAcquireContextA, CryptGenRandom, CryptReleaseContext
-# include <boost/winapi/timers.hpp>
-# include <boost/winapi/get_current_process_id.hpp>
-# include <boost/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_(0)
- {
-#if defined(BOOST_WINDOWS)
- if (!boost::winapi::CryptAcquireContextW(
- &random_,
- NULL,
- NULL,
- boost::winapi::PROV_RSA_FULL_,
- boost::winapi::CRYPT_VERIFYCONTEXT_ | boost::winapi::CRYPT_SILENT_))
- {
- random_ = 0;
- }
-#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::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::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::winapi::DWORD_ procid = boost::winapi::GetCurrentProcessId();
- sha.process_bytes( (unsigned char const*)&procid, sizeof( procid ) );
-
- boost::winapi::DWORD_ threadid = boost::winapi::GetCurrentThreadId();
- sha.process_bytes( (unsigned char const*)&threadid, sizeof( threadid ) );
-
- boost::winapi::LARGE_INTEGER_ ts;
- ts.QuadPart = 0;
- boost::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*)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::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