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-08-28 12:54:26 -04:00
|
|
|
/**
|
2022-11-15 11:32:29 -05:00
|
|
|
* @brief \cite uuid RFC4122 A Universally Unique IDentifier (UUID) URN Namespace
|
2021-08-28 12:54:26 -04:00
|
|
|
*
|
2022-11-15 11:32:29 -05:00
|
|
|
* > This specification defines a Uniform Resource Name namespace
|
2021-08-28 12:54:26 -04:00
|
|
|
* > for UUIDs (Universally Unique IDentifier), also known as GUIDs (Globally
|
|
|
|
* > Unique IDentifier). A UUID is 128 bits long, and can guarantee uniqueness
|
|
|
|
* > across space and time. UUIDs were originally used in the Apollo Network
|
|
|
|
* > Computing System and later in the Open Software Foundation's (OSF)
|
|
|
|
* > Distributed Computing Environment (DCE), and then in Microsoft Windows
|
|
|
|
* > platforms. This specification is derived from the DCE specification with
|
|
|
|
* > the kind permission of the OSF (now known as The Open Group). Information
|
|
|
|
* > from earlier versions of the DCE specification have been incorporated into
|
|
|
|
* > this document.
|
|
|
|
*/
|
2021-05-27 10:59:22 -04:00
|
|
|
namespace UUID {
|
|
|
|
|
2021-08-02 10:09:14 -04:00
|
|
|
/**
|
|
|
|
* @brief The Type enum
|
|
|
|
*/
|
|
|
|
enum Type {
|
2021-08-25 17:20:33 -04:00
|
|
|
NCS, //!< Reserved, NCS backward compatibility.
|
|
|
|
RFC4122, //!< The variant specified in this document.
|
|
|
|
MS, //!< Reserved, Microsoft Corporation backward compatibility
|
|
|
|
RESVERED, //!< Reserved for future definition.
|
2021-08-02 10:09:14 -04:00
|
|
|
NIL
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The RFC4122Version enum
|
|
|
|
*/
|
|
|
|
enum RFC4122Version {
|
|
|
|
VOID = 0b0000,
|
2021-08-25 17:20:33 -04:00
|
|
|
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.
|
2021-08-02 10:09:14 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The Namespace enum
|
|
|
|
*/
|
|
|
|
enum Namespace {
|
2021-08-25 17:20:33 -04:00
|
|
|
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.
|
2021-08-02 10:09:14 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The NCSFields struct
|
|
|
|
*/
|
|
|
|
struct NCSFields {
|
2021-08-25 17:20:33 -04:00
|
|
|
uint64_t time : 48; //!< timestamp
|
|
|
|
uint16_t res; //!< res
|
|
|
|
uint8_t family; //!< family
|
|
|
|
uint64_t node : 56; //!< node number
|
2021-08-02 10:09:14 -04:00
|
|
|
}__attribute__((packed));
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief The RFC4122Fields struct
|
|
|
|
*/
|
|
|
|
struct RFC4122Fields {
|
2021-08-25 17:20:33 -04:00
|
|
|
uint32_t time_low; //!< timestamp low
|
|
|
|
uint16_t time_mid; //!< timestamp mid
|
|
|
|
uint16_t time_hi_version; //!< timestamp high & version
|
|
|
|
uint8_t clock_seq_hi_variant; //!< clock sequence high & variant
|
|
|
|
uint8_t clock_seq_low; //!< clock sequence low
|
|
|
|
uint16_t node_low; //!< node low
|
|
|
|
uint32_t node_high; //!< node high
|
2021-08-02 10:09:14 -04:00
|
|
|
}__attribute__((packed));
|
2021-05-27 10:59:22 -04:00
|
|
|
|
|
|
|
|
2021-08-02 16:29:18 -04:00
|
|
|
/**
|
2021-08-28 12:54:26 -04:00
|
|
|
* @brief 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`.
|
2021-08-02 16:29:18 -04: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&);
|
2021-08-25 17:20:33 -04:00
|
|
|
uuid(const uint8_t * raw);
|
|
|
|
uuid(const char * c_str);
|
|
|
|
uuid(std::string str);
|
2021-05-27 10:59:22 -04:00
|
|
|
|
|
|
|
// accessors
|
2021-08-25 17:20:33 -04:00
|
|
|
const uint8_t* bytes() const;
|
|
|
|
Type type() const;
|
|
|
|
uint16_t version() const;
|
|
|
|
uint64_t time() const;
|
|
|
|
uint16_t sequence() const;
|
|
|
|
uint64_t node() const;
|
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-25 17:20:33 -04:00
|
|
|
void setBytes(const uint8_t * raw);
|
2021-08-02 16:29:18 -04:00
|
|
|
virtual uint16_t uuid1(uint64_t node, uint16_t clock_seq);
|
2021-08-25 17:20:33 -04:00
|
|
|
virtual void uuid4();
|
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&);
|
2021-09-04 17:37:58 -04:00
|
|
|
friend bool operator< (const uuid&, const uuid&);
|
2021-08-02 16:29:18 -04:00
|
|
|
|
|
|
|
// typecast overload
|
2021-08-25 17:20:33 -04:00
|
|
|
operator const uint8_t * () const;
|
|
|
|
operator const std::string () const;
|
2021-08-02 16:29:18 -04:00
|
|
|
|
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
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @brief The hash struct specialization for UUID::uuid
|
|
|
|
*/
|
2021-08-25 17:20:33 -04:00
|
|
|
template<>
|
2021-08-02 10:09:14 -04:00
|
|
|
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
|