CppCommon 1.0.6.0
C++ Common Library
Loading...
Searching...
No Matches
uuid.cpp
Go to the documentation of this file.
1
8
9#include "system/uuid.h"
10
11#include "memory/memory.h"
12
13#include <array>
14#include <chrono>
15#include <random>
16
17#if defined(__MSYS__) || defined(_WIN32) || defined(_WIN64)
18#include <windows.h>
19#include <rpc.h>
20#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
21#include <uuid/uuid.h>
22#endif
23
24namespace CppCommon {
25
26std::string UUID::string() const
27{
28 const char* digits = "0123456789abcdef";
29
30 std::string result(36, '0');
31
32 int index = 0;
33 for (auto value : _data)
34 {
35 result[index++] = digits[(value >> 4) & 0x0F];
36 result[index++] = digits[(value >> 0) & 0x0F];
37 if ((index == 8) || (index == 13) || (index == 18) || (index == 23))
38 result[index++] = '-';
39 }
40
41 return result;
42}
43
45{
46 UUID result;
47#if defined(__MSYS__) || defined(_WIN32) || defined(_WIN64)
48 ::UUID uuid;
49 if (UuidCreateSequential(&uuid) != RPC_S_OK)
50 throwex SystemException("Cannot generate sequential UUID!");
51
52 result._data[0] = (uuid.Data1 >> 24) & 0xFF;
53 result._data[1] = (uuid.Data1 >> 16) & 0xFF;
54 result._data[2] = (uuid.Data1 >> 8) & 0xFF;
55 result._data[3] = (uuid.Data1 >> 0) & 0xFF;
56
57 result._data[4] = (uuid.Data2 >> 8) & 0xFF;
58 result._data[5] = (uuid.Data2 >> 0) & 0xFF;
59
60 result._data[6] = (uuid.Data3 >> 8) & 0xFF;
61 result._data[7] = (uuid.Data3 >> 0) & 0xFF;
62
63 result._data[8] = uuid.Data4[0];
64 result._data[9] = uuid.Data4[1];
65
66 result._data[10] = uuid.Data4[2];
67 result._data[11] = uuid.Data4[3];
68 result._data[12] = uuid.Data4[4];
69 result._data[13] = uuid.Data4[5];
70 result._data[14] = uuid.Data4[6];
71 result._data[15] = uuid.Data4[7];
72#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
73 uuid_t uuid;
74 uuid_generate_time(uuid);
75
76 result._data[0] = uuid[0];
77 result._data[1] = uuid[1];
78 result._data[2] = uuid[2];
79 result._data[3] = uuid[3];
80
81 result._data[4] = uuid[4];
82 result._data[5] = uuid[5];
83
84 result._data[6] = uuid[6];
85 result._data[7] = uuid[7];
86
87 result._data[8] = uuid[8];
88 result._data[9] = uuid[9];
89
90 result._data[10] = uuid[10];
91 result._data[11] = uuid[11];
92 result._data[12] = uuid[12];
93 result._data[13] = uuid[13];
94 result._data[14] = uuid[14];
95 result._data[15] = uuid[15];
96#endif
97 return result;
98}
99
101{
102 UUID result;
103#if defined(__MSYS__) || defined(_WIN32) || defined(_WIN64)
104 ::UUID uuid;
105 if (UuidCreate(&uuid) != RPC_S_OK)
106 throwex SystemException("Cannot generate random UUID!");
107
108 result._data[0] = (uuid.Data1 >> 24) & 0xFF;
109 result._data[1] = (uuid.Data1 >> 16) & 0xFF;
110 result._data[2] = (uuid.Data1 >> 8) & 0xFF;
111 result._data[3] = (uuid.Data1 >> 0) & 0xFF;
112
113 result._data[4] = (uuid.Data2 >> 8) & 0xFF;
114 result._data[5] = (uuid.Data2 >> 0) & 0xFF;
115
116 result._data[6] = (uuid.Data3 >> 8) & 0xFF;
117 result._data[7] = (uuid.Data3 >> 0) & 0xFF;
118
119 result._data[8] = uuid.Data4[0];
120 result._data[9] = uuid.Data4[1];
121
122 result._data[10] = uuid.Data4[2];
123 result._data[11] = uuid.Data4[3];
124 result._data[12] = uuid.Data4[4];
125 result._data[13] = uuid.Data4[5];
126 result._data[14] = uuid.Data4[6];
127 result._data[15] = uuid.Data4[7];
128#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
129 uuid_t uuid;
130 uuid_generate_random(uuid);
131
132 result._data[0] = uuid[0];
133 result._data[1] = uuid[1];
134 result._data[2] = uuid[2];
135 result._data[3] = uuid[3];
136
137 result._data[4] = uuid[4];
138 result._data[5] = uuid[5];
139
140 result._data[6] = uuid[6];
141 result._data[7] = uuid[7];
142
143 result._data[8] = uuid[8];
144 result._data[9] = uuid[9];
145
146 result._data[10] = uuid[10];
147 result._data[11] = uuid[11];
148 result._data[12] = uuid[12];
149 result._data[13] = uuid[13];
150 result._data[14] = uuid[14];
151 result._data[15] = uuid[15];
152#endif
153 return result;
154}
155
157{
158 UUID result;
159
160 // Generate cryptographic strong random bytes
161 Memory::CryptoFill(result._data.data(), result._data.size());
162
163 // Update version and variant fields
164 result._data[6] = (result._data[6] & 0x0F) | 0x40;
165 result._data[8] = (result._data[8] & 0x3F) | 0x80;
166
167 return result;
168}
169
171{
172 UUID result;
173
174 // Generate random bytes
175 std::random_device rd;
176 std::generate(result._data.begin(), result._data.end(), std::ref(rd));
177
178 // Get the current timestamp
179 auto now = std::chrono::system_clock::now();
180 auto duration = now.time_since_epoch();
181 auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
182
183 // Update timestamp fields
184 result._data[0] = (milliseconds >> 40) & 0xFF;
185 result._data[1] = (milliseconds >> 32) & 0xFF;
186 result._data[2] = (milliseconds >> 24) & 0xFF;
187 result._data[3] = (milliseconds >> 16) & 0xFF;
188 result._data[4] = (milliseconds >> 8) & 0xFF;
189 result._data[5] = (milliseconds >> 0) & 0xFF;
190
191 // Update version and variant fields
192 result._data[6] = (result._data[6] & 0x0F) | 0x70;
193 result._data[8] = (result._data[8] & 0x3F) | 0x80;
194
195 return result;
196}
197
198} // namespace CppCommon
static void CryptoFill(void *buffer, size_t size)
Fill the given memory buffer with cryptographic strong random bytes.
Definition memory.cpp:136
System exception.
Definition exceptions.h:107
std::string string() const
Get string from the current UUID in format "00000000-0000-0000-0000-000000000000".
Definition uuid.cpp:26
static UUID Random()
Generate random UUID4 (randomly or pseudo-randomly generated version).
Definition uuid.cpp:100
static UUID Sequential()
Generate sequential UUID1 (time based version).
Definition uuid.cpp:44
static UUID Secure()
Generate secure UUID4 (secure generated version).
Definition uuid.cpp:156
constexpr UUID()
Default constructor.
Definition uuid.h:40
static UUID Database()
Generate database UUID7 (time ordered, high locality version).
Definition uuid.cpp:170
#define throwex
Throw extended exception macro.
Definition exceptions.h:23
Memory management definition.
C++ Common project definitions.
Universally unique identifier (UUID) definition.