update boost on linux

This commit is contained in:
Bassem Girgis
2019-08-10 16:06:25 -05:00
parent 76ad52be58
commit 861b918727
5363 changed files with 483306 additions and 116507 deletions

View File

@@ -0,0 +1,166 @@
// Boost basic_name_generator.hpp header file -----------------------//
// Copyright 2010 Andy Tompkins.
// Copyright 2017 James E. King III
// 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)
#ifndef BOOST_UUID_BASIC_NAME_GENERATOR_HPP
#define BOOST_UUID_BASIC_NAME_GENERATOR_HPP
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <boost/uuid/uuid.hpp>
#include <cstring> // for strlen, wcslen
#include <string>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
using ::size_t;
using ::strlen;
using ::wcslen;
} //namespace std
#endif //BOOST_NO_STDC_NAMESPACE
namespace boost {
namespace uuids {
//! \brief Generate a name based UUID using
//! the provided hashing algorithm that
//! implements the NameHashProvider concept.
template<class HashAlgo>
class basic_name_generator
{
public:
typedef uuid result_type;
typedef typename HashAlgo::digest_type digest_type;
explicit basic_name_generator(uuid const& namespace_uuid_)
: namespace_uuid(namespace_uuid_)
{}
uuid operator()(const char* name) const {
HashAlgo hash;
hash.process_bytes(namespace_uuid.begin(), namespace_uuid.size());
process_characters(hash, name, std::strlen(name));
return hash_to_uuid(hash);
}
uuid operator()(const wchar_t* name) const {
HashAlgo hash;
hash.process_bytes(namespace_uuid.begin(), namespace_uuid.size());
process_characters(hash, name, std::wcslen(name));
return hash_to_uuid(hash);
}
template <typename ch, typename char_traits, typename alloc>
uuid operator()(std::basic_string<ch, char_traits, alloc> const& name) const {
HashAlgo hash;
hash.process_bytes(namespace_uuid.begin(), namespace_uuid.size());
process_characters(hash, name.c_str(), name.length());
return hash_to_uuid(hash);
}
uuid operator()(void const* buffer, std::size_t byte_count) const {
HashAlgo hash;
hash.process_bytes(namespace_uuid.begin(), namespace_uuid.size());
hash.process_bytes(buffer, byte_count);
return hash_to_uuid(hash);
}
private:
// we convert all characters to uint32_t so that each
// character is 4 bytes regardless of sizeof(char) or
// sizeof(wchar_t). We want the name string on any
// platform / compiler to generate the same uuid
// except for char
template <typename char_type>
void process_characters(HashAlgo& hash, char_type const*const characters, std::size_t count) const {
BOOST_STATIC_ASSERT(sizeof(uint32_t) >= sizeof(char_type));
for (std::size_t i=0; i<count; i++) {
std::size_t c = characters[i];
hash.process_byte(static_cast<unsigned char>((c >> 0) & 0xFF));
hash.process_byte(static_cast<unsigned char>((c >> 8) & 0xFF));
hash.process_byte(static_cast<unsigned char>((c >> 16) & 0xFF));
hash.process_byte(static_cast<unsigned char>((c >> 24) & 0xFF));
}
}
void process_characters(HashAlgo& hash, char const*const characters, std::size_t count) const {
hash.process_bytes(characters, count);
}
uuid hash_to_uuid(HashAlgo& hash) const
{
digest_type digest;
hash.get_digest(digest);
BOOST_STATIC_ASSERT(sizeof(digest_type) >= 16);
uuid u;
for (int i=0; i<4; ++i) {
*(u.begin() + i*4+0) = static_cast<uint8_t>((digest[i] >> 24) & 0xFF);
*(u.begin() + i*4+1) = static_cast<uint8_t>((digest[i] >> 16) & 0xFF);
*(u.begin() + i*4+2) = static_cast<uint8_t>((digest[i] >> 8) & 0xFF);
*(u.begin() + i*4+3) = static_cast<uint8_t>((digest[i] >> 0) & 0xFF);
}
// set variant: must be 0b10xxxxxx
*(u.begin()+8) &= 0xBF;
*(u.begin()+8) |= 0x80;
// set version
unsigned char hashver = hash.get_version();
*(u.begin()+6) &= 0x0F; // clear out the relevant bits
*(u.begin()+6) |= (hashver << 4); // and apply them
return u;
}
private:
uuid namespace_uuid;
};
namespace ns {
BOOST_FORCEINLINE uuid dns() {
uuid result = {{
0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1 ,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }};
return result;
}
BOOST_FORCEINLINE uuid url() {
uuid result = {{
0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1 ,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }};
return result;
}
BOOST_FORCEINLINE uuid oid() {
uuid result = {{
0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1 ,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }};
return result;
}
BOOST_FORCEINLINE uuid x500dn() {
uuid result = {{
0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1 ,
0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }};
return result;
}
} // ns
} // uuids
} // boost
#endif // BOOST_UUID_BASIC_NAME_GENERATOR_HPP

View File

@@ -0,0 +1,342 @@
/*
* This RFC 1321 compatible MD5 implementation originated at:
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
*
* Author:
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
*
* This software was written by Alexander Peslyak in 2001. No copyright is
* claimed, and the software is hereby placed in the public domain.
* In case this attempt to disclaim copyright and place the software in the
* public domain is deemed null and void, then the software is
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
* general public under the following terms:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* There's ABSOLUTELY NO WARRANTY, express or implied.
*
*/
// 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)
#ifndef BOOST_UUID_MD5_HPP
#define BOOST_UUID_MD5_HPP
#include <boost/cast.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/uuid/uuid.hpp> // for version
#include <string.h>
namespace boost {
namespace uuids {
namespace detail {
class md5
{
public:
typedef unsigned int(digest_type)[4];
md5()
{
MD5_Init(&ctx_);
}
void process_byte(unsigned char byte)
{
MD5_Update(&ctx_, &byte, 1);
}
void process_bytes(void const* buffer, std::size_t byte_count)
{
MD5_Update(&ctx_, buffer, boost::numeric_cast<unsigned long>(byte_count));
}
void get_digest(digest_type& digest)
{
MD5_Final(reinterpret_cast<unsigned char *>(&digest[0]), &ctx_);
}
unsigned char get_version() const
{
// RFC 4122 Section 4.1.3
return uuid::version_name_based_md5;
}
private:
/* Any 32-bit or wider unsigned integer data type will do */
typedef uint32_t MD5_u32plus;
typedef struct {
MD5_u32plus lo, hi;
MD5_u32plus a, b, c, d;
unsigned char buffer[64];
MD5_u32plus block[16];
} MD5_CTX;
/*
* The basic MD5 functions.
*
* F and G are optimized compared to their RFC 1321 definitions for
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
* implementation.
*/
BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_F(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((z) ^ ((x) & ((y) ^ (z)))); }
BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_G(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((y) ^ ((z) & ((x) ^ (y)))); }
BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_H(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return (((x) ^ (y)) ^ (z)); }
BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_H2(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((x) ^ ((y) ^ (z))); }
BOOST_FORCEINLINE MD5_u32plus BOOST_UUID_DETAIL_MD5_I(MD5_u32plus x, MD5_u32plus y, MD5_u32plus z) { return ((y) ^ ((x) | ~(z))); }
/*
* The MD5 transformation for all four rounds.
*/
#define BOOST_UUID_DETAIL_MD5_STEP(f, a, b, c, d, x, t, s) \
(a) += f((b), (c), (d)) + (x) + (t); \
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
(a) += (b);
/*
* SET reads 4 input bytes in little-endian byte order and stores them in a
* properly aligned word in host byte order.
*
* The check for little-endian architectures that tolerate unaligned memory
* accesses is just an optimization. Nothing will break if it fails to detect
* a suitable architecture.
*
* Unfortunately, this optimization may be a C strict aliasing rules violation
* if the caller's data buffer has effective type that cannot be aliased by
* MD5_u32plus. In practice, this problem may occur if these MD5 routines are
* inlined into a calling function, or with future and dangerously advanced
* link-time optimizations. For the time being, keeping these MD5 routines in
* their own translation unit avoids the problem.
*/
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
#define BOOST_UUID_DETAIL_MD5_SET(n) \
(*(MD5_u32plus *)&ptr[(n) * 4])
#define BOOST_UUID_DETAIL_MD5_GET(n) \
BOOST_UUID_DETAIL_MD5_SET(n)
#else
#define BOOST_UUID_DETAIL_MD5_SET(n) \
(ctx->block[(n)] = \
(MD5_u32plus)ptr[(n) * 4] | \
((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
#define BOOST_UUID_DETAIL_MD5_GET(n) \
(ctx->block[(n)])
#endif
/*
* This processes one or more 64-byte data blocks, but does NOT update the bit
* counters. There are no alignment requirements.
*/
const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
{
const unsigned char *ptr;
MD5_u32plus a, b, c, d;
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
ptr = (const unsigned char *)data;
a = ctx->a;
b = ctx->b;
c = ctx->c;
d = ctx->d;
do {
saved_a = a;
saved_b = b;
saved_c = c;
saved_d = d;
/* Round 1 */
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(0), 0xd76aa478, 7)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(1), 0xe8c7b756, 12)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(2), 0x242070db, 17)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(3), 0xc1bdceee, 22)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(4), 0xf57c0faf, 7)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(5), 0x4787c62a, 12)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(6), 0xa8304613, 17)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(7), 0xfd469501, 22)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(8), 0x698098d8, 7)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(9), 0x8b44f7af, 12)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(10), 0xffff5bb1, 17)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(11), 0x895cd7be, 22)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, a, b, c, d, BOOST_UUID_DETAIL_MD5_SET(12), 0x6b901122, 7)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, d, a, b, c, BOOST_UUID_DETAIL_MD5_SET(13), 0xfd987193, 12)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, c, d, a, b, BOOST_UUID_DETAIL_MD5_SET(14), 0xa679438e, 17)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_F, b, c, d, a, BOOST_UUID_DETAIL_MD5_SET(15), 0x49b40821, 22)
/* Round 2 */
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(1), 0xf61e2562, 5)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(6), 0xc040b340, 9)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(11), 0x265e5a51, 14)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(0), 0xe9b6c7aa, 20)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(5), 0xd62f105d, 5)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(10), 0x02441453, 9)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(15), 0xd8a1e681, 14)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(4), 0xe7d3fbc8, 20)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(9), 0x21e1cde6, 5)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(14), 0xc33707d6, 9)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(3), 0xf4d50d87, 14)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(8), 0x455a14ed, 20)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(13), 0xa9e3e905, 5)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(2), 0xfcefa3f8, 9)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(7), 0x676f02d9, 14)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_G, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(12), 0x8d2a4c8a, 20)
/* Round 3 */
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(5), 0xfffa3942, 4)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(8), 0x8771f681, 11)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(11), 0x6d9d6122, 16)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(14), 0xfde5380c, 23)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(1), 0xa4beea44, 4)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(4), 0x4bdecfa9, 11)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(7), 0xf6bb4b60, 16)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(10), 0xbebfbc70, 23)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(13), 0x289b7ec6, 4)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(0), 0xeaa127fa, 11)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(3), 0xd4ef3085, 16)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(6), 0x04881d05, 23)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(9), 0xd9d4d039, 4)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(12), 0xe6db99e5, 11)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(15), 0x1fa27cf8, 16)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_H2, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(2), 0xc4ac5665, 23)
/* Round 4 */
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(0), 0xf4292244, 6)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(7), 0x432aff97, 10)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(14), 0xab9423a7, 15)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(5), 0xfc93a039, 21)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(12), 0x655b59c3, 6)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(3), 0x8f0ccc92, 10)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(10), 0xffeff47d, 15)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(1), 0x85845dd1, 21)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(8), 0x6fa87e4f, 6)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(15), 0xfe2ce6e0, 10)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(6), 0xa3014314, 15)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(13), 0x4e0811a1, 21)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, a, b, c, d, BOOST_UUID_DETAIL_MD5_GET(4), 0xf7537e82, 6)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, d, a, b, c, BOOST_UUID_DETAIL_MD5_GET(11), 0xbd3af235, 10)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, c, d, a, b, BOOST_UUID_DETAIL_MD5_GET(2), 0x2ad7d2bb, 15)
BOOST_UUID_DETAIL_MD5_STEP(BOOST_UUID_DETAIL_MD5_I, b, c, d, a, BOOST_UUID_DETAIL_MD5_GET(9), 0xeb86d391, 21)
a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
ptr += 64;
} while (size -= 64);
ctx->a = a;
ctx->b = b;
ctx->c = c;
ctx->d = d;
return ptr;
}
void MD5_Init(MD5_CTX *ctx)
{
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
ctx->c = 0x98badcfe;
ctx->d = 0x10325476;
ctx->lo = 0;
ctx->hi = 0;
}
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
{
MD5_u32plus saved_lo;
unsigned long used, available;
saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
ctx->hi++;
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
if (used) {
available = 64 - used;
if (size < available) {
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, available);
data = (const unsigned char *)data + available;
size -= available;
body(ctx, ctx->buffer, 64);
}
if (size >= 64) {
data = body(ctx, data, size & ~(unsigned long)0x3f);
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
#define BOOST_UUID_DETAIL_MD5_OUT(dst, src) \
(dst)[0] = (unsigned char)(src); \
(dst)[1] = (unsigned char)((src) >> 8); \
(dst)[2] = (unsigned char)((src) >> 16); \
(dst)[3] = (unsigned char)((src) >> 24);
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
{
unsigned long used, available;
used = ctx->lo & 0x3f;
ctx->buffer[used++] = 0x80;
available = 64 - used;
if (available < 8) {
memset(&ctx->buffer[used], 0, available);
body(ctx, ctx->buffer, 64);
used = 0;
available = 64;
}
memset(&ctx->buffer[used], 0, available - 8);
ctx->lo <<= 3;
BOOST_UUID_DETAIL_MD5_OUT(&ctx->buffer[56], ctx->lo)
BOOST_UUID_DETAIL_MD5_OUT(&ctx->buffer[60], ctx->hi)
body(ctx, ctx->buffer, 64);
BOOST_UUID_DETAIL_MD5_OUT(&result[0], ctx->a)
BOOST_UUID_DETAIL_MD5_OUT(&result[4], ctx->b)
BOOST_UUID_DETAIL_MD5_OUT(&result[8], ctx->c)
BOOST_UUID_DETAIL_MD5_OUT(&result[12], ctx->d)
memset(ctx, 0, sizeof(*ctx));
}
#undef BOOST_UUID_DETAIL_MD5_OUT
#undef BOOST_UUID_DETAIL_MD5_SET
#undef BOOST_UUID_DETAIL_MD5_GET
#undef BOOST_UUID_DETAIL_MD5_STEP
MD5_CTX ctx_;
};
} // detail
} // uuids
} // boost
#endif // BOOST_UUID_MD5_HPP

View File

@@ -0,0 +1,91 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// Platform-specific random entropy provider
//
#ifndef BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP
#define BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_unsigned.hpp>
#include <boost/uuid/entropy_error.hpp>
#include <climits>
#include <iterator>
// Detection of the platform is separated from inclusion of the correct
// header to facilitate mock testing of the provider implementations.
#include <boost/uuid/detail/random_provider_detect_platform.hpp>
#include <boost/uuid/detail/random_provider_include_platform.hpp>
namespace boost {
namespace uuids {
namespace detail {
//! \brief Contains code common to all random_provider implementations.
//! \note random_provider_base is required to provide this method:
//! void get_random_bytes(void *buf, size_t siz);
//! \note noncopyable because of some base implementations so
//! this makes it uniform across platforms to avoid any
//! porting surprises
class random_provider :
public detail::random_provider_base
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider)
public:
BOOST_DEFAULTED_FUNCTION(random_provider(), {})
random_provider(BOOST_RV_REF(random_provider) that) BOOST_NOEXCEPT :
detail::random_provider_base(boost::move(static_cast< detail::random_provider_base& >(that)))
{
}
random_provider& operator= (BOOST_RV_REF(random_provider) that) BOOST_NOEXCEPT
{
static_cast< detail::random_provider_base& >(*this) = boost::move(static_cast< detail::random_provider_base& >(that));
return *this;
}
//! Leverage the provider as a SeedSeq for
//! PseudoRandomNumberGeneration seeing.
//! \note: See Boost.Random documentation for more details
template<class Iter>
void generate(Iter first, Iter last)
{
typedef typename std::iterator_traits<Iter>::value_type value_type;
BOOST_STATIC_ASSERT(is_integral<value_type>::value);
BOOST_STATIC_ASSERT(is_unsigned<value_type>::value);
BOOST_STATIC_ASSERT(sizeof(value_type) * CHAR_BIT >= 32);
for (; first != last; ++first)
{
get_random_bytes(&*first, sizeof(*first));
*first &= (std::numeric_limits<boost::uint32_t>::max)();
}
}
//! Return the name of the selected provider
const char * name() const
{
return BOOST_UUID_RANDOM_PROVIDER_STRINGIFY(BOOST_UUID_RANDOM_PROVIDER_NAME);
}
};
} // detail
} // uuids
} // boost
#endif // BOOST_UUID_DETAIL_RANDOM_PROVIDER_HPP

View File

@@ -0,0 +1,33 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// "A Replacement Call for Random"
// https://man.openbsd.org/arc4random.3
//
#include <cstddef>
#include <stdlib.h>
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
public:
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
arc4random_buf(buf, siz);
}
};
} // detail
} // uuids
} // boost

View File

@@ -0,0 +1,103 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// BCrypt provider for entropy
//
#include <cstddef>
#include <boost/config.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/move/core.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/winapi/bcrypt.hpp>
#include <boost/winapi/get_last_error.hpp>
#include <boost/throw_exception.hpp>
#if defined(BOOST_UUID_FORCE_AUTO_LINK) || (!defined(BOOST_ALL_NO_LIB) && !defined(BOOST_UUID_RANDOM_PROVIDER_NO_LIB))
# define BOOST_LIB_NAME "bcrypt"
# define BOOST_AUTO_LINK_NOMANGLE
# include <boost/config/auto_link.hpp>
# undef BOOST_AUTO_LINK_NOMANGLE
#endif
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider_base)
public:
random_provider_base()
: hProv_(NULL)
{
boost::winapi::NTSTATUS_ status =
boost::winapi::BCryptOpenAlgorithmProvider(
&hProv_,
boost::winapi::BCRYPT_RNG_ALGORITHM_,
NULL,
0);
if (BOOST_UNLIKELY(status != 0))
{
BOOST_THROW_EXCEPTION(entropy_error(status, "BCryptOpenAlgorithmProvider"));
}
}
random_provider_base(BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT : hProv_(that.hProv_)
{
that.hProv_ = NULL;
}
random_provider_base& operator= (BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT
{
destroy();
hProv_ = that.hProv_;
that.hProv_ = NULL;
return *this;
}
~random_provider_base() BOOST_NOEXCEPT
{
destroy();
}
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
boost::winapi::NTSTATUS_ status =
boost::winapi::BCryptGenRandom(
hProv_,
static_cast<boost::winapi::PUCHAR_>(buf),
boost::numeric_cast<boost::winapi::ULONG_>(siz),
0);
if (BOOST_UNLIKELY(status != 0))
{
BOOST_THROW_EXCEPTION(entropy_error(status, "BCryptGenRandom"));
}
}
private:
void destroy() BOOST_NOEXCEPT
{
if (hProv_)
{
boost::ignore_unused(boost::winapi::BCryptCloseAlgorithmProvider(hProv_, 0));
}
}
private:
boost::winapi::BCRYPT_ALG_HANDLE_ hProv_;
};
} // detail
} // uuids
} // boost

View File

@@ -0,0 +1,74 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// Platform-specific random entropy provider platform detection
//
#ifndef BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_DETECTION_HPP
#define BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_DETECTION_HPP
#include <boost/predef/library/c/cloudabi.h>
#include <boost/predef/library/c/gnu.h>
#include <boost/predef/os/bsd/open.h>
#include <boost/predef/os/windows.h>
// Note: Don't use Boost.Predef to detect Linux and Android as it may give different results depending on header inclusion order.
// https://github.com/boostorg/predef/issues/81#issuecomment-413329061
#if (defined(__linux__) || defined(__linux) || defined(linux)) && (!defined(__ANDROID__) || __ANDROID_API__ >= 28)
#include <sys/syscall.h>
#if defined(SYS_getrandom)
#define BOOST_UUID_RANDOM_PROVIDER_HAS_GETRANDOM
#endif // defined(SYS_getrandom)
#endif
//
// Platform Detection - will load in the correct header and
// will define the class <tt>random_provider_base</tt>.
//
#if BOOST_OS_BSD_OPEN >= BOOST_VERSION_NUMBER(2, 1, 0) || BOOST_LIB_C_CLOUDABI
# define BOOST_UUID_RANDOM_PROVIDER_ARC4RANDOM
# define BOOST_UUID_RANDOM_PROVIDER_NAME arc4random
#elif BOOST_OS_WINDOWS
# include <boost/winapi/config.hpp>
# if BOOST_WINAPI_PARTITION_APP_SYSTEM && \
!defined(BOOST_UUID_RANDOM_PROVIDER_FORCE_WINCRYPT) && \
!defined(_WIN32_WCE) && \
(BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6)
# define BOOST_UUID_RANDOM_PROVIDER_BCRYPT
# define BOOST_UUID_RANDOM_PROVIDER_NAME bcrypt
# elif BOOST_WINAPI_PARTITION_DESKTOP || BOOST_WINAPI_PARTITION_SYSTEM
# define BOOST_UUID_RANDOM_PROVIDER_WINCRYPT
# define BOOST_UUID_RANDOM_PROVIDER_NAME wincrypt
# else
# error Unable to find a suitable windows entropy provider
# endif
#elif defined(BOOST_UUID_RANDOM_PROVIDER_HAS_GETRANDOM) && !defined(BOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX) && !defined(BOOST_UUID_RANDOM_PROVIDER_DISABLE_GETRANDOM)
# define BOOST_UUID_RANDOM_PROVIDER_GETRANDOM
# define BOOST_UUID_RANDOM_PROVIDER_NAME getrandom
#elif BOOST_LIB_C_GNU >= BOOST_VERSION_NUMBER(2, 25, 0) && !defined(BOOST_UUID_RANDOM_PROVIDER_FORCE_POSIX)
# define BOOST_UUID_RANDOM_PROVIDER_GETENTROPY
# define BOOST_UUID_RANDOM_PROVIDER_NAME getentropy
#else
# define BOOST_UUID_RANDOM_PROVIDER_POSIX
# define BOOST_UUID_RANDOM_PROVIDER_NAME posix
#endif
#define BOOST_UUID_RANDOM_PROVIDER_STRINGIFY2(X) #X
#define BOOST_UUID_RANDOM_PROVIDER_STRINGIFY(X) BOOST_UUID_RANDOM_PROVIDER_STRINGIFY2(X)
#if defined(BOOST_UUID_RANDOM_PROVIDER_SHOW)
#pragma message("BOOST_UUID_RANDOM_PROVIDER_NAME " BOOST_UUID_RANDOM_PROVIDER_STRINGIFY(BOOST_UUID_RANDOM_PROVIDER_NAME))
#endif
#endif // BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_DETECTION_HPP

View File

@@ -0,0 +1,40 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// getentropy() capable platforms
//
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <cerrno>
#include <cstddef>
#include <unistd.h>
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
public:
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
int res = getentropy(buf, siz);
if (BOOST_UNLIKELY(-1 == res))
{
int err = errno;
BOOST_THROW_EXCEPTION(entropy_error(err, "getentropy"));
}
}
};
} // detail
} // uuids
} // boost

View File

@@ -0,0 +1,77 @@
//
// Copyright (c) 2018 Andrey Semashev
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// getrandom() capable platforms
//
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <boost/predef/library/c/gnu.h>
#include <cerrno>
#include <cstddef>
#if !defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM)
#if BOOST_LIB_C_GNU >= BOOST_VERSION_NUMBER(2, 25, 0)
#define BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER
#elif defined(__has_include)
#if __has_include(<sys/random.h>)
#define BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER
#endif
#endif
#endif // !defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM)
#if defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER)
#include <sys/random.h>
#else
#include <stddef.h> // ssize_t
#endif
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
public:
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
std::size_t offset = 0;
while (offset < siz)
{
ssize_t sz = get_random(static_cast< char* >(buf) + offset, siz - offset, 0u);
if (BOOST_UNLIKELY(sz < 0))
{
int err = errno;
if (err == EINTR)
continue;
BOOST_THROW_EXCEPTION(entropy_error(err, "getrandom"));
}
offset += sz;
}
}
private:
static ssize_t get_random(void *buf, std::size_t size, unsigned int flags)
{
#if defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM)
return BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_IMPL_GETRANDOM(buf, size, flags);
#elif defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM_HAS_LIBC_WRAPPER)
return ::getrandom(buf, size, flags);
#else
return ::syscall(SYS_getrandom, buf, size, flags);
#endif
}
};
} // detail
} // uuids
} // boost

View File

@@ -0,0 +1,29 @@
//
// Copyright (c) 2017 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// Platform-specific random entropy provider platform definition
//
#ifndef BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_INCLUDE_HPP
#define BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_INCLUDE_HPP
#if defined(BOOST_UUID_RANDOM_PROVIDER_ARC4RANDOM)
# include <boost/uuid/detail/random_provider_arc4random.ipp>
#elif defined(BOOST_UUID_RANDOM_PROVIDER_BCRYPT)
# include <boost/uuid/detail/random_provider_bcrypt.ipp>
#elif defined(BOOST_UUID_RANDOM_PROVIDER_GETENTROPY)
# include <boost/uuid/detail/random_provider_getentropy.ipp>
#elif defined(BOOST_UUID_RANDOM_PROVIDER_GETRANDOM)
# include <boost/uuid/detail/random_provider_getrandom.ipp>
#elif defined(BOOST_UUID_RANDOM_PROVIDER_POSIX)
# include <boost/uuid/detail/random_provider_posix.ipp>
#elif defined(BOOST_UUID_RANDOM_PROVIDER_WINCRYPT)
# include <boost/uuid/detail/random_provider_wincrypt.ipp>
#endif
#endif // BOOST_UUID_DETAIL_RANDOM_PROVIDER_PLATFORM_INCLUDE_HPP

View File

@@ -0,0 +1,120 @@
/* boost uuid/detail/random_provider_posix implementation
*
* Copyright Jens Maurer 2000
* Copyright 2007 Andy Tompkins.
* Copyright Steven Watanabe 2010-2011
* Copyright 2017 James E. King III
*
* 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$
*/
#include <boost/config.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/move/core.hpp>
#include <boost/throw_exception.hpp>
#include <boost/uuid/entropy_error.hpp>
#include <cerrno>
#include <cstddef>
#include <fcntl.h> // open
#include <sys/stat.h>
#include <sys/types.h>
#if defined(BOOST_HAS_UNISTD_H)
#include <unistd.h>
#endif
#ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE
#define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE ::close
#endif
#ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN
#define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN ::open
#endif
#ifndef BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ
#define BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ ::read
#endif
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider_base)
public:
random_provider_base()
: fd_(-1)
{
int flags = O_RDONLY;
#if defined(O_CLOEXEC)
flags |= O_CLOEXEC;
#endif
fd_ = BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_OPEN("/dev/urandom", flags);
if (BOOST_UNLIKELY(-1 == fd_))
{
int err = errno;
BOOST_THROW_EXCEPTION(entropy_error(err, "open /dev/urandom"));
}
}
random_provider_base(BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT : fd_(that.fd_)
{
that.fd_ = -1;
}
random_provider_base& operator= (BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT
{
destroy();
fd_ = that.fd_;
that.fd_ = -1;
return *this;
}
~random_provider_base() BOOST_NOEXCEPT
{
destroy();
}
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
std::size_t offset = 0;
while (offset < siz)
{
ssize_t sz = BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_READ(
fd_, static_cast<char *>(buf) + offset, siz - offset);
if (BOOST_UNLIKELY(sz < 0))
{
int err = errno;
if (err == EINTR)
continue;
BOOST_THROW_EXCEPTION(entropy_error(err, "read"));
}
offset += sz;
}
}
private:
void destroy() BOOST_NOEXCEPT
{
if (fd_ >= 0)
{
boost::ignore_unused(BOOST_UUID_RANDOM_PROVIDER_POSIX_IMPL_CLOSE(fd_));
}
}
private:
int fd_;
};
} // detail
} // uuids
} // boost

View File

@@ -0,0 +1,109 @@
/* boost uuid/detail/random_provider_wincrypt implementation
*
* Copyright Jens Maurer 2000
* Copyright 2007 Andy Tompkins.
* Copyright Steven Watanabe 2010-2011
* Copyright 2017 James E. King III
*
* 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$
*/
#include <cstddef>
#include <boost/config.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/move/core.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/winapi/crypt.hpp>
#include <boost/winapi/get_last_error.hpp>
#include <boost/throw_exception.hpp>
#if defined(BOOST_UUID_FORCE_AUTO_LINK) || (!defined(BOOST_ALL_NO_LIB) && !defined(BOOST_UUID_RANDOM_PROVIDER_NO_LIB))
# if defined(_WIN32_WCE)
# define BOOST_LIB_NAME "coredll"
# else
# define BOOST_LIB_NAME "advapi32"
# endif
# define BOOST_AUTO_LINK_NOMANGLE
# include <boost/config/auto_link.hpp>
# undef BOOST_AUTO_LINK_NOMANGLE
#endif
namespace boost {
namespace uuids {
namespace detail {
class random_provider_base
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(random_provider_base)
public:
random_provider_base()
: hProv_(0)
{
boost::winapi::BOOL_ res = boost::winapi::CryptAcquireContextW(
&hProv_,
NULL,
NULL,
boost::winapi::PROV_RSA_FULL_,
boost::winapi::CRYPT_VERIFYCONTEXT_ | boost::winapi::CRYPT_SILENT_);
if (BOOST_UNLIKELY(!res))
{
boost::winapi::DWORD_ err = boost::winapi::GetLastError();
BOOST_THROW_EXCEPTION(entropy_error(err, "CryptAcquireContext"));
}
}
random_provider_base(BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT : hProv_(that.hProv_)
{
that.hProv_ = 0;
}
random_provider_base& operator= (BOOST_RV_REF(random_provider_base) that) BOOST_NOEXCEPT
{
destroy();
hProv_ = that.hProv_;
that.hProv_ = 0;
return *this;
}
~random_provider_base() BOOST_NOEXCEPT
{
destroy();
}
//! Obtain entropy and place it into a memory location
//! \param[in] buf the location to write entropy
//! \param[in] siz the number of bytes to acquire
void get_random_bytes(void *buf, std::size_t siz)
{
boost::winapi::BOOL_ res = boost::winapi::CryptGenRandom(
hProv_,
boost::numeric_cast<boost::winapi::DWORD_>(siz),
static_cast<boost::winapi::BYTE_ *>(buf));
if (BOOST_UNLIKELY(!res))
{
boost::winapi::DWORD_ err = boost::winapi::GetLastError();
BOOST_THROW_EXCEPTION(entropy_error(err, "CryptGenRandom"));
}
}
private:
void destroy() BOOST_NOEXCEPT
{
if (hProv_)
{
boost::ignore_unused(boost::winapi::CryptReleaseContext(hProv_, 0));
}
}
private:
boost::winapi::HCRYPTPROV_ hProv_;
};
} // detail
} // uuids
} // boost

View File

@@ -1,5 +1,3 @@
// boost/uuid/sha1.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
@@ -16,9 +14,10 @@
#define BOOST_UUID_SHA1_H
#include <boost/static_assert.hpp>
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <boost/uuid/uuid.hpp> // for version
#include <cstddef>
#include <stdexcept>
#include <string>
#ifdef BOOST_NO_STDC_NAMESPACE
@@ -42,7 +41,7 @@ inline unsigned int left_rotate(unsigned int x, std::size_t n)
class sha1
{
public:
typedef unsigned int(&digest_type)[5];
typedef unsigned int(digest_type)[5];
public:
sha1();
@@ -52,7 +51,8 @@ public:
void process_block(void const* bytes_begin, void const* bytes_end);
void process_bytes(void const* buffer, std::size_t byte_count);
void get_digest(digest_type digest);
void get_digest(digest_type& digest);
unsigned char get_version() const;
private:
void process_block();
@@ -183,7 +183,13 @@ inline void sha1::process_block()
h_[4] += e;
}
inline void sha1::get_digest(digest_type digest)
inline unsigned char sha1::get_version() const
{
// RFC 4122 Section 4.1.3
return uuid::version_name_based_sha1;
}
inline void sha1::get_digest(digest_type& digest)
{
// append the bit '1' to the message
process_byte_impl(0x80);
@@ -207,7 +213,7 @@ inline void sha1::get_digest(digest_type digest)
}
}
// append length of message (before pre-processing)
// append length of message (before pre-processing)
// as a 64-bit big-endian integer
process_byte_impl( static_cast<unsigned char>((bit_count_high>>24) & 0xFF) );
process_byte_impl( static_cast<unsigned char>((bit_count_high>>16) & 0xFF) );

View File

@@ -5,13 +5,13 @@
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file uuid/detail/uuid_generic.hpp
* \file uuid/detail/uuid_generic.ipp
*
* \brief This header contains generic implementation of \c boost::uuid operations.
*/
#ifndef BOOST_UUID_DETAIL_UUID_GENERIC_HPP_INCLUDED_
#define BOOST_UUID_DETAIL_UUID_GENERIC_HPP_INCLUDED_
#ifndef BOOST_UUID_DETAIL_UUID_GENERIC_IPP_INCLUDED_
#define BOOST_UUID_DETAIL_UUID_GENERIC_IPP_INCLUDED_
#include <string.h>
@@ -48,4 +48,4 @@ inline bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
} // namespace uuids
} // namespace boost
#endif // BOOST_UUID_DETAIL_UUID_GENERIC_HPP_INCLUDED_
#endif // BOOST_UUID_DETAIL_UUID_GENERIC_IPP_INCLUDED_

View File

@@ -5,13 +5,13 @@
* http://www.boost.org/LICENSE_1_0.txt)
*/
/*!
* \file uuid/detail/uuid_x86.hpp
* \file uuid/detail/uuid_x86.ipp
*
* \brief This header contains optimized SSE implementation of \c boost::uuid operations.
*/
#ifndef BOOST_UUID_DETAIL_UUID_X86_HPP_INCLUDED_
#define BOOST_UUID_DETAIL_UUID_X86_HPP_INCLUDED_
#ifndef BOOST_UUID_DETAIL_UUID_X86_IPP_INCLUDED_
#define BOOST_UUID_DETAIL_UUID_X86_IPP_INCLUDED_
// MSVC does not always have immintrin.h (at least, not up to MSVC 10), so include the appropriate header for each instruction set
#if defined(BOOST_UUID_USE_SSE41)
@@ -132,4 +132,4 @@ inline bool operator< (uuid const& lhs, uuid const& rhs) BOOST_NOEXCEPT
} // namespace uuids
} // namespace boost
#endif // BOOST_UUID_DETAIL_UUID_X86_HPP_INCLUDED_
#endif // BOOST_UUID_DETAIL_UUID_X86_IPP_INCLUDED_

View File

@@ -0,0 +1,46 @@
//
// Copyright (c) 2017, 2018 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// Entropy error class
//
#ifndef BOOST_UUID_RANDOM_ENTROPY_ERROR_HPP
#define BOOST_UUID_RANDOM_ENTROPY_ERROR_HPP
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <stdexcept>
#include <string>
namespace boost {
namespace uuids {
//! \brief Given boost::system::system_error is in a module that
//! is not header-only, we define our own exception type
//! to handle entropy provider errors instead,
class BOOST_SYMBOL_VISIBLE entropy_error : public std::runtime_error
{
public:
entropy_error(boost::intmax_t errCode, const std::string& message)
: std::runtime_error(message)
, m_errcode(errCode)
{
}
virtual boost::intmax_t errcode() const
{
return m_errcode;
}
private:
boost::intmax_t m_errcode;
};
} // uuids
} // boost
#endif // BOOST_UUID_RANDOM_ENTROPY_ERROR_HPP

View File

@@ -1,125 +1,38 @@
// Boost name_generator.hpp header file ----------------------------------------------//
// Boost name_generator.hpp header file -----------------------------//
// Copyright 2010 Andy Tompkins.
// Copyright 2017 James E. King III
// 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)
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UUID_NAME_GENERATOR_HPP
#define BOOST_UUID_NAME_GENERATOR_HPP
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/sha1.hpp>
#include <boost/assert.hpp>
#include <string>
#include <cstring> // for strlen, wcslen
#include <boost/config.hpp>
#include <boost/uuid/name_generator_sha1.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
using ::strlen;
using ::wcslen;
} //namespace std
#endif //BOOST_NO_STDC_NAMESPACE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace uuids {
// generate a name-based uuid
// TODO: add in common namesspace uuids
class name_generator {
public:
typedef uuid result_type;
//! \deprecated
//! \brief this provides backwards compatibility with previous boost
//! releases however it is now deprecated to ensure that once
//! a new hashing algorithm is defined for name generation that
//! there is no confusion - at that time this will be removed.
typedef name_generator_sha1 name_generator;
explicit name_generator(uuid const& namespace_uuid_)
: namespace_uuid(namespace_uuid_)
{}
//! \brief this provides the latest name generator hashing algorithm
//! regardless of boost release; if you do not need stable
//! name generation across releases then this will suffice
typedef name_generator_sha1 name_generator_latest;
uuid operator()(const char* name) {
reset();
process_characters(name, std::strlen(name));
return sha_to_uuid();
}
uuid operator()(const wchar_t* name) {
reset();
process_characters(name, std::wcslen(name));
return sha_to_uuid();
}
template <typename ch, typename char_traits, typename alloc>
uuid operator()(std::basic_string<ch, char_traits, alloc> const& name) {
reset();
process_characters(name.c_str(), name.length());
return sha_to_uuid();
}
uuid operator()(void const* buffer, std::size_t byte_count) {
reset();
sha.process_bytes(buffer, byte_count);
return sha_to_uuid();
};
private:
// we convert all characters to uint32_t so that each
// character is 4 bytes reguardless of sizeof(char) or
// sizeof(wchar_t). We want the name string on any
// platform / compiler to generate the same uuid
// except for char
template <typename char_type>
void process_characters(char_type const*const characters, size_t count) {
BOOST_ASSERT(sizeof(uint32_t) >= sizeof(char_type));
for (size_t i=0; i<count; i++) {
uint32_t c = characters[i];
sha.process_byte(static_cast<unsigned char>((c >> 0) & 0xFF));
sha.process_byte(static_cast<unsigned char>((c >> 8) & 0xFF));
sha.process_byte(static_cast<unsigned char>((c >> 16) & 0xFF));
sha.process_byte(static_cast<unsigned char>((c >> 24) & 0xFF));
}
}
void process_characters(char const*const characters, size_t count) {
sha.process_bytes(characters, count);
}
void reset()
{
sha.reset();
sha.process_bytes(namespace_uuid.begin(), namespace_uuid.size());
}
uuid sha_to_uuid()
{
unsigned int digest[5];
sha.get_digest(digest);
uuid u;
for (int i=0; i<4; ++i) {
*(u.begin() + i*4+0) = static_cast<uint8_t>((digest[i] >> 24) & 0xFF);
*(u.begin() + i*4+1) = static_cast<uint8_t>((digest[i] >> 16) & 0xFF);
*(u.begin() + i*4+2) = static_cast<uint8_t>((digest[i] >> 8) & 0xFF);
*(u.begin() + i*4+3) = static_cast<uint8_t>((digest[i] >> 0) & 0xFF);
}
// set variant
// must be 0b10xxxxxx
*(u.begin()+8) &= 0xBF;
*(u.begin()+8) |= 0x80;
// set version
// must be 0b0101xxxx
*(u.begin()+6) &= 0x5F; //0b01011111
*(u.begin()+6) |= 0x50; //0b01010000
return u;
}
private:
uuid namespace_uuid;
detail::sha1 sha;
};
}} // namespace boost::uuids
} // uuids
} // boost
#endif // BOOST_UUID_NAME_GENERATOR_HPP

View File

@@ -0,0 +1,25 @@
// Boost name_generator_md5.hpp header file ------------------------//
// Copyright 2017 James E. King III
// 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)
#ifndef BOOST_UUID_NAME_GENERATOR_MD5_HPP
#define BOOST_UUID_NAME_GENERATOR_MD5_HPP
#include <boost/uuid/basic_name_generator.hpp>
#include <boost/uuid/detail/md5.hpp>
namespace boost {
namespace uuids {
//! \brief MD5 hashing is defined in RFC 4122 however it is not commonly
//! used; the definition is provided for backwards compatibility.
typedef basic_name_generator<detail::md5> name_generator_md5;
} // uuids
} // boost
#endif // BOOST_UUID_NAME_GENERATOR_MD5_HPP

View File

@@ -0,0 +1,26 @@
// Boost name_generator_sha1.hpp header file ------------------------//
// Copyright 2010 Andy Tompkins.
// Copyright 2017 James E. King III
// 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)
#ifndef BOOST_UUID_NAME_GENERATOR_SHA1_HPP
#define BOOST_UUID_NAME_GENERATOR_SHA1_HPP
#include <boost/uuid/basic_name_generator.hpp>
#include <boost/uuid/detail/sha1.hpp>
namespace boost {
namespace uuids {
//! \brief SHA1 hashing is the default method defined in RFC 4122 to be
//! used when backwards compatibility is not necessary.
typedef basic_name_generator<detail::sha1> name_generator_sha1;
} // uuids
} // boost
#endif // BOOST_UUID_NAME_GENERATOR_SHA1_HPP

View File

@@ -1,6 +1,7 @@
// Boost random_generator.hpp header file ----------------------------------------------//
// Copyright 2010 Andy Tompkins.
// Copyright 2017 James E. King III
// 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)
@@ -8,85 +9,144 @@
#ifndef BOOST_UUID_RANDOM_GENERATOR_HPP
#define BOOST_UUID_RANDOM_GENERATOR_HPP
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/seed_rng.hpp>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/move/core.hpp>
#include <boost/move/utility_core.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/assert.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/tti/has_member_function.hpp>
#include <boost/uuid/detail/random_provider.hpp>
#include <boost/uuid/uuid.hpp>
#include <limits>
namespace boost {
namespace uuids {
// generate a random-based uuid
namespace detail {
template<class U>
U& set_uuid_random_vv(U& u)
{
// set variant
// must be 0b10xxxxxx
*(u.begin() + 8) &= 0xBF;
*(u.begin() + 8) |= 0x80;
// set version
// must be 0b0100xxxx
*(u.begin() + 6) &= 0x4F; //0b01001111
*(u.begin() + 6) |= 0x40; //0b01000000
return u;
}
BOOST_TTI_HAS_MEMBER_FUNCTION(seed)
}
//! generate a random-based uuid
//! \param[in] UniformRandomNumberGenerator see Boost.Random documentation
template <typename UniformRandomNumberGenerator>
class basic_random_generator {
class basic_random_generator
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_random_generator)
private:
typedef uniform_int<unsigned long> distribution_type;
typedef variate_generator<UniformRandomNumberGenerator*, distribution_type> generator_type;
struct null_deleter
struct impl
{
void operator()(void const *) const {}
generator_type generator;
explicit impl(UniformRandomNumberGenerator* purng_arg) :
generator(purng_arg, distribution_type((std::numeric_limits<unsigned long>::min)(), (std::numeric_limits<unsigned long>::max)()))
{
}
virtual ~impl() {}
BOOST_DELETED_FUNCTION(impl(impl const&))
BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
};
struct urng_holder
{
UniformRandomNumberGenerator urng;
};
#if defined(BOOST_MSVC)
#pragma warning(push)
// 'this' : used in base member initializer list
#pragma warning(disable: 4355)
#endif
struct self_contained_impl :
public urng_holder,
public impl
{
self_contained_impl() : impl(&this->urng_holder::urng)
{
}
};
#if defined(BOOST_MSVC)
#pragma warning(pop)
#endif
public:
typedef uuid result_type;
// default constructor creates the random number generator
basic_random_generator()
: pURNG(new UniformRandomNumberGenerator)
, generator
( pURNG.get()
, distribution_type
( (std::numeric_limits<unsigned long>::min)()
, (std::numeric_limits<unsigned long>::max)()
)
)
// default constructor creates the random number generator and
// if the UniformRandomNumberGenerator is a PseudoRandomNumberGenerator
// then it gets seeded by a random_provider.
basic_random_generator() : m_impl(new self_contained_impl())
{
// seed the random number generator
detail::seed(*pURNG);
// seed the random number generator if it is capable
seed(static_cast< self_contained_impl* >(m_impl)->urng);
}
// keep a reference to a random number generator
// don't seed a given random number generator
explicit basic_random_generator(UniformRandomNumberGenerator& gen)
: pURNG(&gen, null_deleter())
, generator
( pURNG.get()
, distribution_type
( (std::numeric_limits<unsigned long>::min)()
, (std::numeric_limits<unsigned long>::max)()
)
)
{}
explicit basic_random_generator(UniformRandomNumberGenerator& gen) : m_impl(new impl(&gen))
{
}
// keep a pointer to a random number generator
// don't seed a given random number generator
explicit basic_random_generator(UniformRandomNumberGenerator* pGen)
: pURNG(pGen, null_deleter())
, generator
( pURNG.get()
, distribution_type
( (std::numeric_limits<unsigned long>::min)()
, (std::numeric_limits<unsigned long>::max)()
)
)
explicit basic_random_generator(UniformRandomNumberGenerator* gen) : m_impl(new impl(gen))
{
BOOST_ASSERT(pURNG);
BOOST_ASSERT(!!gen);
}
uuid operator()()
basic_random_generator(BOOST_RV_REF(basic_random_generator) that) BOOST_NOEXCEPT : m_impl(that.m_impl)
{
uuid u;
that.m_impl = 0;
}
basic_random_generator& operator= (BOOST_RV_REF(basic_random_generator) that) BOOST_NOEXCEPT
{
delete m_impl;
m_impl = that.m_impl;
that.m_impl = 0;
return *this;
}
~basic_random_generator()
{
delete m_impl;
}
result_type operator()()
{
result_type u;
int i=0;
unsigned long random_value = generator();
for (uuid::iterator it=u.begin(); it!=u.end(); ++it, ++i) {
unsigned long random_value = m_impl->generator();
for (uuid::iterator it = u.begin(), end = u.end(); it != end; ++it, ++i) {
if (i==sizeof(unsigned long)) {
random_value = generator();
random_value = m_impl->generator();
i = 0;
}
@@ -94,26 +154,75 @@ public:
*it = static_cast<uuid::value_type>((random_value >> (i*8)) & 0xFF);
}
// set variant
// must be 0b10xxxxxx
*(u.begin()+8) &= 0xBF;
*(u.begin()+8) |= 0x80;
// set version
// must be 0b0100xxxx
*(u.begin()+6) &= 0x4F; //0b01001111
*(u.begin()+6) |= 0x40; //0b01000000
return u;
return detail::set_uuid_random_vv(u);
}
private:
shared_ptr<UniformRandomNumberGenerator> pURNG;
generator_type generator;
// Detect whether UniformRandomNumberGenerator has a seed() method which indicates that
// it is a PseudoRandomNumberGenerator and needs a seed to initialize it. This allows
// basic_random_generator to take any type of UniformRandomNumberGenerator and still
// meet the post-conditions for the default constructor.
template<class MaybePseudoRandomNumberGenerator>
typename boost::enable_if<detail::has_member_function_seed<MaybePseudoRandomNumberGenerator, void> >::type
seed(MaybePseudoRandomNumberGenerator& rng)
{
detail::random_provider seeder;
rng.seed(seeder);
}
template<class MaybePseudoRandomNumberGenerator>
typename boost::disable_if<detail::has_member_function_seed<MaybePseudoRandomNumberGenerator, void> >::type
seed(MaybePseudoRandomNumberGenerator&)
{
}
impl* m_impl;
};
//! \brief a far less complex random generator that uses
//! operating system provided entropy which will
//! satisfy the majority of use cases
class random_generator_pure
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(random_generator_pure)
public:
typedef uuid result_type;
BOOST_DEFAULTED_FUNCTION(random_generator_pure(), {})
random_generator_pure(BOOST_RV_REF(random_generator_pure) that) BOOST_NOEXCEPT :
prov_(boost::move(that.prov_))
{
}
random_generator_pure& operator= (BOOST_RV_REF(random_generator_pure) that) BOOST_NOEXCEPT
{
prov_ = boost::move(that.prov_);
return *this;
}
//! \returns a random, valid uuid
//! \throws entropy_error
result_type operator()()
{
result_type result;
prov_.get_random_bytes(&result, sizeof(result_type));
return detail::set_uuid_random_vv(result);
}
private:
detail::random_provider prov_;
};
#if defined(BOOST_UUID_RANDOM_GENERATOR_COMPAT)
typedef basic_random_generator<mt19937> random_generator;
#else
typedef random_generator_pure random_generator;
typedef basic_random_generator<mt19937> random_generator_mt19937;
#endif
}} // namespace boost::uuids
#endif //BOOST_UUID_RANDOM_GENERATOR_HPP
#endif // BOOST_UUID_RANDOM_GENERATOR_HPP

View File

@@ -1,321 +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/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

View File

@@ -15,6 +15,7 @@
#include <algorithm> // for find
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <boost/config.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std {
@@ -32,8 +33,8 @@ namespace uuids {
// and be more efficient
// would like to accept the following forms:
// 0123456789abcdef0123456789abcdef
// 01234567-89ab-cdef-0123456789abcdef
// {01234567-89ab-cdef-0123456789abcdef}
// 01234567-89ab-cdef-0123-456789abcdef
// {01234567-89ab-cdef-0123-456789abcdef}
// {0123456789abcdef0123456789abcdef}
// others?
struct string_generator {
@@ -81,8 +82,9 @@ struct string_generator {
}
}
if (has_dashes) {
if (i == 6 || i == 8 || i == 10) {
// if there are dashes, they must be in every slot
else if (i == 6 || i == 8 || i == 10) {
if (has_dashes == true) {
if (is_dash(c)) {
c = get_next_char(begin, end);
} else {
@@ -90,6 +92,7 @@ struct string_generator {
}
}
}
*it_byte = get_value(c);
@@ -103,6 +106,11 @@ struct string_generator {
c = get_next_char(begin, end);
check_close_brace(c, open_brace_char);
}
// check end of string - any additional data is an invalid uuid
if (begin != end) {
throw_invalid();
}
return u;
}
@@ -118,27 +126,33 @@ private:
}
unsigned char get_value(char c) const {
static char const*const digits_begin = "0123456789abcdefABCDEF";
static char const*const digits_end = digits_begin + 22;
static char const digits_begin[] = "0123456789abcdefABCDEF";
static size_t digits_len = (sizeof(digits_begin) / sizeof(char)) - 1;
static char const*const digits_end = digits_begin + digits_len;
static unsigned char const values[] =
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15
, static_cast<unsigned char>(-1) };
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15 };
char const* d = std::find(digits_begin, digits_end, c);
return values[d - digits_begin];
size_t pos = std::find(digits_begin, digits_end, c) - digits_begin;
if (pos >= digits_len) {
throw_invalid();
}
return values[pos];
}
unsigned char get_value(wchar_t c) const {
static wchar_t const*const digits_begin = L"0123456789abcdefABCDEF";
static wchar_t const*const digits_end = digits_begin + 22;
static wchar_t const digits_begin[] = L"0123456789abcdefABCDEF";
static size_t digits_len = (sizeof(digits_begin) / sizeof(wchar_t)) - 1;
static wchar_t const*const digits_end = digits_begin + digits_len;
static unsigned char const values[] =
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15
, static_cast<unsigned char>(-1) };
{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,10,11,12,13,14,15 };
wchar_t const* d = std::find(digits_begin, digits_end, c);
return values[d - digits_begin];
size_t pos = std::find(digits_begin, digits_end, c) - digits_begin;
if (pos >= digits_len) {
throw_invalid();
}
return values[pos];
}
bool is_dash(char c) const {
@@ -174,7 +188,7 @@ private:
}
}
void throw_invalid() const {
BOOST_NORETURN void throw_invalid() const {
BOOST_THROW_EXCEPTION(std::runtime_error("invalid uuid string"));
}
};

View File

@@ -200,9 +200,9 @@ struct is_pod<uuids::uuid> : true_type {};
#endif
#if defined(BOOST_UUID_USE_SSE2)
#include <boost/uuid/detail/uuid_x86.hpp>
#include <boost/uuid/detail/uuid_x86.ipp>
#else
#include <boost/uuid/detail/uuid_generic.hpp>
#include <boost/uuid/detail/uuid_generic.ipp>
#endif
#if defined(_MSC_VER)

View File

@@ -0,0 +1,40 @@
//
// Copyright (c) 2018 James E. King III
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENCE_1_0.txt)
//
// std::hash support for uuid
//
#ifndef BOOST_UUID_HASH_HPP
#define BOOST_UUID_HASH_HPP
#include <boost/config.hpp>
#include <boost/container_hash/hash.hpp>
#include <boost/uuid/uuid_io.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
#include <cstddef>
#include <functional>
namespace std
{
template<>
struct hash<boost::uuids::uuid>
{
std::size_t operator () (const boost::uuids::uuid& value) const BOOST_NOEXCEPT
{
return boost::hash_value(to_string(value));
}
};
}
#endif /* !BOOST_NO_CXX11_HDR_FUNCTIONAL */
#endif /* !BOOST_UUID_HASH_HPP */