2021-05-27 10:59:22 -04:00
|
|
|
/*
|
|
|
|
uuid.h
|
|
|
|
|
|
|
|
Copyright (c) 2021 Kevin Matz (kevin.matz@gmail.com)
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
|
|
copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
SOFTWARE.
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <cstring>
|
|
|
|
#include <string>
|
|
|
|
|
2021-08-13 10:05:32 -04:00
|
|
|
#define UUID_LENGTH 16
|
|
|
|
|
2021-05-27 10:59:22 -04:00
|
|
|
// RFC4122 A Universally Unique IDentifier (UUID) URN Namespace
|
|
|
|
namespace UUID {
|
|
|
|
|
2021-08-02 10:09:14 -04:00
|
|
|
/**
|
|
|
|
* @brief The Type enum
|
|
|
|
*/
|
|
|
|
enum Type {
|
|
|
|
NCS, // Reserved, NCS backward compatibility.
|
|
|
|
RFC4122, // The variant specified in this document.
|
|
|
|
MS, // Reserved, Microsoft Corporation backward compatibility
|
|
|
|
RESVERED, // Reserved for future definition.
|
|
|
|
NIL
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The RFC4122Version enum
|
|
|
|
*/
|
|
|
|
enum RFC4122Version {
|
|
|
|
VOID = 0b0000,
|
|
|
|
TIME = 0b0001, // The time-based version specified in this document.
|
|
|
|
DCE = 0b0010, // DCE Security version, with embedded POSIX UIDs.
|
|
|
|
MD5 = 0b0011, // The name-based version that uses MD5 hashing.
|
|
|
|
RAND = 0b0100, // The randomly or pseudo-randomly generated version.
|
|
|
|
SHA1 = 0b0101 // The name-based version that uses SHA-1 hashing.
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The Namespace enum
|
|
|
|
*/
|
|
|
|
enum Namespace {
|
|
|
|
DNS, // the name string is a fully-qualified domain name.
|
|
|
|
URL, // the name string is a URL.
|
|
|
|
OID, // the name string is an ISO OID.
|
|
|
|
X500 // the name string is an X.500 DN in DER or a text output format.
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The NCSFields struct
|
|
|
|
*/
|
|
|
|
struct NCSFields {
|
|
|
|
uint64_t time : 48;
|
|
|
|
uint16_t res;
|
|
|
|
uint8_t family;
|
|
|
|
uint64_t node : 56;
|
|
|
|
}__attribute__((packed));
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The RFC4122Fields struct
|
|
|
|
*/
|
|
|
|
struct RFC4122Fields {
|
|
|
|
uint32_t time_low;
|
|
|
|
uint16_t time_mid;
|
|
|
|
uint16_t time_hi_version;
|
|
|
|
uint8_t clock_seq_hi_variant;
|
|
|
|
uint8_t clock_seq_low;
|
|
|
|
uint16_t node_low;
|
|
|
|
uint32_t node_high;
|
|
|
|
}__attribute__((packed));
|
2021-05-27 10:59:22 -04:00
|
|
|
|
|
|
|
|
2021-08-02 16:29:18 -04:00
|
|
|
/**
|
|
|
|
* @brief UUID_TICKS_BETWEEK_EPOCH
|
|
|
|
* The number of 100 ns ticks between the Gregorian epoch `1582-10-15 00:00:00`
|
|
|
|
* and the Unix epoch `1970-01-01 00:00:00`.
|
|
|
|
*/
|
|
|
|
static const uint64_t UUID_TICKS_BETWEEK_EPOCH = 122192928000000000;
|
|
|
|
|
2021-08-15 23:36:29 -04:00
|
|
|
//static const char* NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
|
|
|
//static const char* NAMESPACE_URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
|
|
|
|
//static const char* NAMESPACE_OID = "6ba7b812-9dad-11d1-80b4-00c04fd430c8";
|
|
|
|
//static const char* NAMESPACE_X500 = "6ba7b814-9dad-11d1-80b4-00c04fd430c8";
|
2021-08-02 10:09:14 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The uuid class
|
|
|
|
*/
|
|
|
|
class uuid {
|
|
|
|
public:
|
2021-05-27 10:59:22 -04:00
|
|
|
uuid();
|
2021-08-02 16:29:18 -04:00
|
|
|
uuid(const uuid&);
|
|
|
|
uuid(const uint8_t * raw) : uuid() { fromArray_(raw); };
|
2021-08-16 21:20:19 -04:00
|
|
|
uuid(const char * c_str) : uuid() { fromCstring_(c_str); };
|
2021-08-02 16:29:18 -04:00
|
|
|
uuid(std::string str) : uuid() { fromString_(str); };
|
2021-05-27 10:59:22 -04:00
|
|
|
|
|
|
|
// accessors
|
2021-08-02 16:29:18 -04:00
|
|
|
const uint8_t * bytes() const { return raw_; };
|
2021-08-02 10:09:14 -04:00
|
|
|
Type type() const { return type_; };
|
|
|
|
uint16_t version() const { return version_; };
|
|
|
|
uint64_t time() const { return timestamp_; };
|
|
|
|
uint16_t sequence() const { return clock_seq_; };
|
|
|
|
uint64_t node() const { return node_; };
|
2021-05-27 10:59:22 -04:00
|
|
|
|
|
|
|
// output
|
|
|
|
std::string hex() const; // '12345678123456781234567812345678'
|
2021-08-22 16:57:46 -04:00
|
|
|
std::string string() const;// '12345678-1234-5678-1234-567812345678'
|
2021-05-27 10:59:22 -04:00
|
|
|
std::string urn() const; // 'urn:uuid:12345678-1234-5678-1234-567812345678'
|
|
|
|
|
|
|
|
// creators
|
2021-08-16 21:20:19 -04:00
|
|
|
void setBytes(const uint8_t * raw) { fromArray_(raw); }
|
2021-08-02 16:29:18 -04:00
|
|
|
virtual uint16_t uuid1(uint64_t node, uint16_t clock_seq);
|
2021-08-02 10:09:14 -04:00
|
|
|
// virtual void uuid3(Namespace, std::string) {};
|
2021-08-02 16:29:18 -04:00
|
|
|
virtual void uuid4(); // very low quality of random
|
2021-08-02 10:09:14 -04:00
|
|
|
// virtual void uuid5(Namespace, std::string) {};
|
2021-05-27 10:59:22 -04:00
|
|
|
|
2021-08-02 16:29:18 -04:00
|
|
|
// operator overloads
|
|
|
|
uuid& operator= (const uuid& other);
|
|
|
|
friend bool operator== (const uuid&, const uuid&);
|
|
|
|
|
|
|
|
// typecast overload
|
|
|
|
operator const uint8_t * () const { return raw_; };
|
|
|
|
operator const std::string () const { return string(); };
|
|
|
|
|
2021-05-27 10:59:22 -04:00
|
|
|
private:
|
2021-08-22 17:41:12 -04:00
|
|
|
uint8_t raw_[UUID_LENGTH] = {0};
|
2021-05-27 10:59:22 -04:00
|
|
|
Type type_;
|
2021-07-26 15:41:02 -04:00
|
|
|
uint16_t version_;
|
|
|
|
uint64_t timestamp_;
|
|
|
|
uint16_t clock_seq_;
|
|
|
|
uint64_t node_;
|
2021-05-27 10:59:22 -04:00
|
|
|
|
2021-08-02 16:29:18 -04:00
|
|
|
void fromArray_(const uint8_t *);
|
|
|
|
void fromCstring_(const char *);
|
|
|
|
void fromString_(std::string);
|
|
|
|
|
|
|
|
void setType_();
|
|
|
|
void setBytes_();
|
|
|
|
void setNCSBytes_();
|
|
|
|
void setRFC4122Bytes_();
|
2021-05-27 10:59:22 -04:00
|
|
|
|
2021-08-02 16:29:18 -04:00
|
|
|
void setFields_();
|
|
|
|
void setNCSFields_();
|
|
|
|
void setRFC4122Fields_();
|
2021-07-26 15:41:02 -04:00
|
|
|
|
2021-08-02 16:29:18 -04:00
|
|
|
uint64_t now_();
|
2021-08-02 10:09:14 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace UUID
|
|
|
|
|
|
|
|
|
|
|
|
namespace std
|
|
|
|
{
|
|
|
|
template<>
|
|
|
|
/**
|
|
|
|
* @brief The hash struct specialization for UUID::uuid
|
|
|
|
*/
|
|
|
|
struct hash<UUID::uuid>
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @brief operator ()
|
|
|
|
* @param id
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
size_t operator()(UUID::uuid const& id) const noexcept
|
|
|
|
{
|
2021-08-02 16:29:18 -04:00
|
|
|
return std::hash<std::string>{}(id.hex());
|
2021-08-02 10:09:14 -04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
} // namespace std
|