2
0
mirror of https://github.com/boostorg/random.git synced 2026-01-19 04:22:17 +00:00

Rearrange the componenents in libs/random and create a library for random_device. Fixes #3672

[SVN r60199]
This commit is contained in:
Steven Watanabe
2010-03-05 19:12:45 +00:00
parent 3fc357f9b3
commit bc73588c7e
16 changed files with 146 additions and 7 deletions

18
build/Jamfile.v2 Normal file
View File

@@ -0,0 +1,18 @@
# Jamfile.v2
#
# Copyright (c) 2010
# Steven Watanabe
#
# 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)
project /boost/random
: source-location ../src
: requirements <link>shared:<define>BOOST_RANDOM_DYN_LINK
: usage-requirements <link>shared:<define>BOOST_RANDOM_DYN_LINK
;
lib boost_random : [ glob *.cpp ] ;
boost-install boost_random ;

View File

@@ -23,6 +23,7 @@
#include <boost/config.hpp>
#include <boost/utility.hpp> // noncopyable
#include <boost/integer_traits.hpp> // compile-time integral limits
#include <boost/random/detail/auto_link.hpp>
namespace boost {
@@ -61,6 +62,12 @@ namespace boost {
* pseudo-device, which blocks on reads if the entropy pool has no more
* random bits available.
*
* <b>Inplementation Note for Windows</b>
*
* On the Windows operating system, token is interpreted as the name
* of a cryptographic service provider. By default \random_device uses
* MS_DEF_PROV.
*
* <b>Performance</b>
*
* The test program <a href="\boost/libs/random/nondet_random_speed.cpp">

View File

@@ -0,0 +1,42 @@
/* boost random auto_link.hpp header file
*
* Copyright Steven Watanabe 2010
* 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)
*
* $Id$
*/
#ifndef BOOST_RANDOM_DETAIL_AUTO_LINK_HPP
#define BOOST_RANDOM_DETAIL_AUTO_LINK_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_DECLSPEC
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)
#if defined(BOOST_RANDOM_SOURCE)
#define BOOST_RANDOM_DECL __declspec(dllexport)
#else
#define BOOST_RANDOM_DECL __declspec(dllimport)
#endif
#endif
#endif
#ifndef BOOST_RANDOM_DECL
#define BOOST_RANDOM_DECL
#endif
#if !defined(BOOST_RANDOM_NO_LIB) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_RANDOM_SOURCE)
#define BOOST_LIB_NAME boost_random
#if defined(BOOST_RANDOM_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)
#define BOOST_DYN_LINK
#endif
#include <boost/config/auto_link.hpp>
#endif
#endif

View File

@@ -1,6 +1,7 @@
/* boost random_device.cpp implementation
*
* Copyright Jens Maurer 2000
* Copyright Steven Watanabe 2010
* 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)
@@ -9,6 +10,8 @@
*
*/
#define BOOST_RANDOM_SOURCE
#include <boost/nondet_random.hpp>
#include <string>
#include <cassert>
@@ -22,7 +25,79 @@ const boost::random_device::result_type boost::random_device::max_value;
#endif
#if defined(__linux__) || defined (__FreeBSD__)
#if defined(BOOST_WINDOWS)
#include <windows.h>
#include <wincrypt.h>
#include <stdexcept> // std::invalid_argument
const char * const boost::random_device::default_token = "";
class boost::random_device::impl
{
public:
impl(const std::string & token) : path(token) {
std::basic_string<TCHAR> prov_name(token.begin(), token.end());
if(prov_name.empty()) prov_name = MS_DEF_PROV;
TCHAR buffer[80];
DWORD type;
DWORD len;
// Find the type of the provider
for(DWORD i = 0; ; ++i) {
len = sizeof(buffer);
if(!CryptEnumProviders(i, NULL, 0, &type, buffer, &len)) {
error("Could not find provider");
}
if(buffer == prov_name) {
break;
}
}
if(!CryptAcquireContext(&hProv, NULL, prov_name.c_str(), type,
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
error("Failed to aqcuire CSP context");
}
}
~impl() {
if(!CryptReleaseContext(hProv, 0)) error("could not release CSP");
}
unsigned int next() {
unsigned int result;
if(!CryptGenRandom(hProv, sizeof(result),
static_cast<BYTE*>(static_cast<void*>(&result)))) {
error("error while reading");
}
return result;
}
private:
void error(const std::string & msg) {
DWORD error_code = GetLastError();
TCHAR buf[80];
DWORD num = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0,
buf,
sizeof(buf),
NULL);
throw std::invalid_argument("boost::random_device: " + msg +
" random-number pseudo-device " + path +
": " + std::string(&buf[0], &buf[0] + num));
}
const std::string path;
HCRYPTPROV hProv;
};
#else
// the default is the unlimited capacity device, using some secure hash
// try "/dev/random" for blocking when the entropy pool has drained
@@ -90,8 +165,7 @@ private:
int fd;
};
#endif // __linux__ || __FreeBSD__
#endif // BOOST_WINDOWS
boost::random_device::random_device(const std::string& token)
: pimpl(new impl(token))

View File

@@ -7,12 +7,10 @@
# bring in rules for testing
import testing ;
project
: source-location ..
;
project /boost/random/test ;
run random_test.cpp ;
run random_demo.cpp ;
run ../example/random_demo.cpp ;
run validate.cpp ;
local all-urngs =