32 #include "device/network.hpp" 33 #include "crypto/hash/md5.hpp" 34 #include "crypto/hash/sha1.hpp" 79 static const uint64_t TIME_LOW_MASK = 0x00000000FFFFFFFF;
82 static const uint64_t TIME_MID_MASK = 0x000000000000FFFF;
85 static const uint64_t TIME_HIGH_MASK = 0x0000000000000FFF;
88 static const uint32_t SEQ_LOW_MASK = 0x00FF;
91 static const uint32_t SEQ_HIGH_MASK = 0x3F00;
103 uint16_t _clockSeqLow;
106 uint16_t _clockSeqHighRes;
131 _midTime(uuid._midTime),
132 _highTime(uuid._highTime),
133 _clockSeqLow(uuid._clockSeqLow),
134 _clockSeqHighRes(uuid._clockSeqHighRes),
161 const std::string& data =
"") {
163 std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now();
164 auto epoch = now.time_since_epoch();
165 int64_t timestamp = (std::chrono::duration_cast<std::chrono::nanoseconds>(epoch).count());
166 getRandomEngine().seed(timestamp);
169 uuid._version = version;
172 case Uuid::Version::MAC_ADDRESS:
175 case Uuid::Version::DCE_SECURITY:
178 case Uuid::Version::MD5_HASH:
181 case Uuid::Version::RANDOM:
184 case Uuid::Version::SHA1_HASH:
201 const std::string& macAddress =
"") {
203 uint64_t timestamp = getUtcTimestamp();
204 uuid._lowTime = timestamp & TIME_LOW_MASK;
205 uuid._midTime = (timestamp >> 32) & TIME_MID_MASK;
206 uuid._highTime = (timestamp >> 48) & TIME_HIGH_MASK;
210 uint16_t clockSeq = getDistSeq()(getRandomEngine());
211 uuid._clockSeqLow = clockSeq & SEQ_LOW_MASK;
212 uuid._clockSeqHighRes = (clockSeq & SEQ_HIGH_MASK) >> 8;
213 uuid._clockSeqHighRes |= 0x80;
217 std::string macAddr = macAddress;
227 std::size_t last = 0;
228 std::string macHexStr =
"";
233 pos = macAddr.find(
':', last);
234 macHexStr += macAddr.substr(last, pos - last);
235 }
while(pos != std::string::npos);
236 uuid._node = std::stoull(macHexStr,0,16);
248 const std::array<uint8_t,16>& digest = hash.
digest();
251 uuid._lowTime = digest[0]
252 + (
static_cast<uint32_t
>(digest[1]) << 8)
253 + (
static_cast<uint32_t
>(digest[2]) << 16)
254 + (
static_cast<uint32_t
>(digest[3]) << 24);
255 uuid._midTime = digest[4]
256 + (
static_cast<uint16_t
>(digest[5]) << 8);
257 uuid._highTime = digest[6]
258 + (
static_cast<uint16_t
>(digest[7]) << 8);
259 uuid._highTime = uuid._highTime & TIME_HIGH_MASK;
263 uuid._clockSeqLow = digest[9];
264 uuid._clockSeqHighRes = digest[8];
265 uuid._clockSeqHighRes |= 0x80;
269 uuid._node = digest[10]
270 + (
static_cast<uint64_t
>(digest[11]) << 8)
271 + (
static_cast<uint64_t
>(digest[12]) << 16)
272 + (
static_cast<uint64_t
>(digest[13]) << 24)
273 + (
static_cast<uint64_t
>(digest[14]) << 32)
274 + (
static_cast<uint64_t
>(digest[15]) << 40);
284 static std::uniform_int_distribution<uint16_t> dist16;
285 static std::uniform_int_distribution<uint32_t> dist32;
286 static std::uniform_int_distribution<uint64_t> dist64(0, 0xFFFFFFFFFFFF);
289 uuid._lowTime = dist32(getRandomEngine());
290 uuid._midTime = dist16(getRandomEngine());
291 uuid._highTime = dist16(getRandomEngine()) & TIME_HIGH_MASK;
295 uint16_t clockSeq = getDistSeq()(getRandomEngine());
296 uuid._clockSeqLow = clockSeq & SEQ_LOW_MASK;
297 uuid._clockSeqHighRes = (clockSeq & SEQ_HIGH_MASK) >> 8;
298 uuid._clockSeqHighRes |= 0x80;
302 uuid._node = dist64(getRandomEngine());
314 const std::array<uint8_t,20>& digest = hash.
digest();
317 uuid._lowTime = digest[0]
318 + (
static_cast<uint32_t
>(digest[1]) << 8)
319 + (
static_cast<uint32_t
>(digest[2]) << 16)
320 + (
static_cast<uint32_t
>(digest[3]) << 24);
321 uuid._midTime = digest[4]
322 + (
static_cast<uint16_t
>(digest[5]) << 8);
323 uuid._highTime = digest[6]
324 + (
static_cast<uint16_t
>(digest[7]) << 8);
325 uuid._highTime = uuid._highTime & TIME_HIGH_MASK;
329 uuid._clockSeqLow = digest[9];
330 uuid._clockSeqHighRes = digest[8];
331 uuid._clockSeqHighRes |= 0x80;
335 uuid._node = digest[10]
336 + (
static_cast<uint64_t
>(digest[11]) << 8)
337 + (
static_cast<uint64_t
>(digest[12]) << 16)
338 + (
static_cast<uint64_t
>(digest[13]) << 24)
339 + (
static_cast<uint64_t
>(digest[14]) << 32)
340 + (
static_cast<uint64_t
>(digest[15]) << 40);
350 static uint64_t getUtcTimestamp() {
351 static const uint64_t UTC_OFFSET = 0x01B21DD213814000;
352 std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now();
353 auto epoch = now.time_since_epoch();
354 int64_t timestamp = (std::chrono::duration_cast<std::chrono::nanoseconds>(epoch).count()) / 100;
355 return UTC_OFFSET + (uint64_t)timestamp;
363 static inline std::mt19937& getRandomEngine() {
364 static std::mt19937 engine;
373 static inline std::uniform_int_distribution<uint16_t>& getDistSeq() {
374 static std::uniform_int_distribution<uint16_t> distSeq(0, SEQ_HIGH_MASK);
385 std::ostringstream out;
387 << std::setfill(
'0') << std::setw(8) << _lowTime <<
'-' 388 << std::setfill(
'0') << std::setw(4) << _midTime <<
'-' 389 << std::setfill(
'0') << std::setw(1) << _version
390 << std::setfill(
'0') << std::setw(3) << _highTime <<
'-' 391 << std::setfill(
'0') << std::setw(2) << _clockSeqHighRes
392 << std::setfill(
'0') << std::setw(2) << _clockSeqLow <<
'-' 393 << std::setfill(
'0') << std::setw(12) << _node;
443 return _clockSeqHighRes;
478 template<
class CharT,
class Traits>
479 std::basic_ostream<CharT, Traits>&
480 operator<<(std::basic_ostream<CharT, Traits>& out,
const anch::Uuid& uuid) {
481 std::ios_base::fmtflags flags = out.flags();
483 << std::setfill(
'0') << std::setw(8) << uuid.getLowTime() <<
'-' 484 << std::setfill(
'0') << std::setw(4) << uuid.getMidTime() <<
'-' 485 << std::setfill(
'0') << std::setw(1) << uuid.getVersion()
486 << std::setfill(
'0') << std::setw(3) << uuid.getHighTime() <<
'-' 487 << std::setfill(
'0') << std::setw(2) << uuid.getClockSeqHighRes()
488 << std::setfill(
'0') << std::setw(2) << uuid.getClockSeqLow() <<
'-' 489 << std::setfill(
'0') << std::setw(12) << uuid.getNode();
494 #endif // _ANCH_UUID_H_ uint32_t getLowTime() const
Definition: uuid.hpp:406
Uuid()
Definition: uuid.hpp:121
uint16_t getClockSeqHighRes() const
Definition: uuid.hpp:442
Definition: networkInterface.hpp:38
const std::string & getMacAddress() const
Definition: networkInterface.hpp:112
uint16_t getMidTime() const
Definition: uuid.hpp:415
virtual ~Uuid()
Definition: uuid.hpp:145
Version
Definition: uuid.hpp:59
static void generateUuidVersion3(Uuid &uuid, const std::string &data)
Definition: uuid.hpp:246
uint16_t getHighTime() const
Definition: uuid.hpp:424
static void generateUuidVersion4(Uuid &uuid)
Definition: uuid.hpp:283
AnCH framework base namespace.
Definition: base64.hpp:28
virtual const std::array< uint8_t, 20 > & digest() const override
Definition: sha1.cpp:72
Uuid(const Uuid &uuid)
Definition: uuid.hpp:130
UUID generator and parser.
Definition: uuid.hpp:50
bool isLocalhost() const
Definition: networkInterface.hpp:157
uint16_t getClockSeqLow() const
Definition: uuid.hpp:433
MD5 hash algorithm implementation.
Definition: md5.hpp:40
static void generateUuid(Uuid &uuid, anch::Uuid::Version version=anch::Uuid::Version::RANDOM, const std::string &data="")
Definition: uuid.hpp:159
static const std::map< std::string, anch::device::NetworkInterface > & getInterfaces()
Definition: network.cpp:104
std::string toString() const
Definition: uuid.hpp:384
static void generateUuidVersion1(Uuid &uuid, const std::string &macAddress="")
Definition: uuid.hpp:200
uint64_t getNode() const
Definition: uuid.hpp:451
static void generateUuidVersion5(Uuid &uuid, const std::string &data)
Definition: uuid.hpp:312
anch::Uuid::Version getVersion() const
Definition: uuid.hpp:460
virtual const std::array< uint8_t, 16 > & digest() const override
Definition: md5.cpp:73
SHA1 hash algorithm implementation.
Definition: sha1.hpp:38