TEC
A lightweight C++ library enabling safe, efficient execution in multithreaded and concurrent systems.
Loading...
Searching...
No Matches
tec_guid.hpp
Go to the documentation of this file.
1// Time-stamp: <Last changed 2026-02-20 15:57:42 by magnolia>
2/*----------------------------------------------------------------------
3------------------------------------------------------------------------
4Copyright (c) 2020-2026 The Emacs Cat (https://github.com/olddeuteronomy/tec).
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17------------------------------------------------------------------------
18----------------------------------------------------------------------*/
25#pragma once
26
27#include <random>
28#include <array>
29#include <cstdint>
30#include <string>
31#include <iomanip>
32#include <sstream>
33#include <cstring>
34
35#include "tec/tec_def.hpp" // IWYU pragma: keep
36
37
38namespace tec {
39
41using uuid_t = std::array<std::uint8_t, 16>;
42
43namespace guid {
44
45namespace details {
46
48struct randgen {
49 static std::mt19937_64& get_rng() {
50 thread_local static std::mt19937_64 rng__{std::random_device{}()};
51 return rng__;
52 }
53}; // randgen
54
55} // namespace details
56
57
62{
63 uuid_t uuid;
64 //
65 // Fill with cryptographically strong random bytes if possible,
66 // otherwise high-quality pseudo-random bytes.
67 //
68 std::uniform_int_distribution<std::uint8_t> dist{0, 255};
69 for (auto& byte : uuid) {
70 byte = dist(details::randgen::get_rng());
71 }
72 //
73 // Set version (4) --> bits 12-15 of byte 6
74 //
75 uuid[6] = (uuid[6] & 0x0F) | 0x40; // version 4
76 //
77 // Set variant (RFC 4122) --> bits 6-7 of byte 8 = 10
78 //
79 uuid[8] = (uuid[8] & 0x3F) | 0x80; // variant 1 (10xx xxxx)
80 return uuid;
81}
82
83inline std::ostream& operator<<(std::ostream& os, const uuid_t& uuid) {
84 auto flags = os.flags();
85 os << std::hex << std::setfill('0');
86 for (int i = 0; i < 16; ++i) {
87 if (i == 4 || i == 6 || i == 8 || i == 10) os << '-';
88 os << std::setw(2) << static_cast<unsigned>(uuid[i]);
89 }
90 os.flags(flags); // restore original flags
91 return os;
92}
93
94/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
95*
96* Formatting helpers
97*
98 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
99
103inline std::string to_string(const uuid_t& uuid)
104{
105 std::ostringstream os;
106 os << uuid;
107 std::string result = os.str();
108 return result;
109}
110
115inline std::string generate()
116{
117 return to_string(generate_v4());
118}
119
120
121} // namespace guid
122
123} // namespace tec
124
125
126/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
127*
128* Quick usage examples
129*
130 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
131
132/*
133int main()
134{
135 for (int i = 0; i < 5; ++i)
136 {
137 std::cout << tec::guid::generate() << "\n";
138 }
139
140 // Example outputs:
141 // 8f4e2b1a-7d9c-4e3f-9a2b-c5d8e1f60789
142 // d7a94f12-3b6e-41c5-8f2d-9e0c1a5b6789
143 // ...
144}
145*/
Thread-local randomness.
Definition tec_guid.hpp:48
Common definitions and utilities for the tec namespace.
std::string generate()
Generate new GUID as hex string (in lowercase).
Definition tec_guid.hpp:115
std::array< std::uint8_t, 16 > uuid_t
16-byte GUID
Definition tec_guid.hpp:41
std::string to_string(const uuid_t &uuid)
Convert GUID to hex string (in lowercase).
Definition tec_guid.hpp:103
uuid_t generate_v4()
Generates 16-byte uuid_t version 4.
Definition tec_guid.hpp:61