1 // Boost name_generator.hpp header file ----------------------------------------------//
3 // Copyright 2010 Andy Tompkins.
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_UUID_NAME_GENERATOR_HPP
9 #define BOOST_UUID_NAME_GENERATOR_HPP
11 #include <boost/uuid/uuid.hpp>
12 #include <boost/uuid/sha1.hpp>
13 #include <boost/assert.hpp>
15 #include <cstring> // for strlen, wcslen
17 #ifdef BOOST_NO_STDC_NAMESPACE
22 #endif //BOOST_NO_STDC_NAMESPACE
27 // generate a name-based uuid
28 // TODO: add in common namesspace uuids
29 class name_generator {
31 typedef uuid result_type;
33 explicit name_generator(uuid const& namespace_uuid_)
34 : namespace_uuid(namespace_uuid_)
37 uuid operator()(const char* name) {
39 process_characters(name, std::strlen(name));
43 uuid operator()(const wchar_t* name) {
45 process_characters(name, std::wcslen(name));
49 template <typename ch, typename char_traits, typename alloc>
50 uuid operator()(std::basic_string<ch, char_traits, alloc> const& name) {
52 process_characters(name.c_str(), name.length());
56 uuid operator()(void const* buffer, std::size_t byte_count) {
58 sha.process_bytes(buffer, byte_count);
63 // we convert all characters to uint32_t so that each
64 // character is 4 bytes reguardless of sizeof(char) or
65 // sizeof(wchar_t). We want the name string on any
66 // platform / compiler to generate the same uuid
68 template <typename char_type>
69 void process_characters(char_type const*const characters, size_t count) {
70 BOOST_ASSERT(sizeof(uint32_t) >= sizeof(char_type));
72 for (size_t i=0; i<count; i++) {
73 uint32_t c = characters[i];
74 sha.process_byte(static_cast<unsigned char>((c >> 0) & 0xFF));
75 sha.process_byte(static_cast<unsigned char>((c >> 8) & 0xFF));
76 sha.process_byte(static_cast<unsigned char>((c >> 16) & 0xFF));
77 sha.process_byte(static_cast<unsigned char>((c >> 24) & 0xFF));
81 void process_characters(char const*const characters, size_t count) {
82 sha.process_bytes(characters, count);
88 sha.process_bytes(namespace_uuid.begin(), namespace_uuid.size());
93 unsigned int digest[5];
95 sha.get_digest(digest);
98 for (int i=0; i<4; ++i) {
99 *(u.begin() + i*4+0) = static_cast<uint8_t>((digest[i] >> 24) & 0xFF);
100 *(u.begin() + i*4+1) = static_cast<uint8_t>((digest[i] >> 16) & 0xFF);
101 *(u.begin() + i*4+2) = static_cast<uint8_t>((digest[i] >> 8) & 0xFF);
102 *(u.begin() + i*4+3) = static_cast<uint8_t>((digest[i] >> 0) & 0xFF);
106 // must be 0b10xxxxxx
107 *(u.begin()+8) &= 0xBF;
108 *(u.begin()+8) |= 0x80;
111 // must be 0b0101xxxx
112 *(u.begin()+6) &= 0x5F; //0b01011111
113 *(u.begin()+6) |= 0x50; //0b01010000
123 }} // namespace boost::uuids
125 #endif // BOOST_UUID_NAME_GENERATOR_HPP