blob: 07909c0c4a1c489bf4c78b2f56597af81f0eb4fe [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include <iosfwd>
#include <string>
namespace uuid {
// Number of bytes in a UUID.
constexpr size_t kUuidSize = 16;
// The internal components of a UUID.
// c.f., RFC 4122 Section 4.1.2.
// Most users should the |Uuid| type directly, below.
struct RawUuid {
uint32_t time_low;
uint16_t time_mid;
uint16_t time_hi_and_version;
uint8_t clock_seq_hi_and_reserved;
uint8_t clock_seq_low;
uint8_t node[6];
static_assert(sizeof(RawUuid) == kUuidSize);
// A Universally Unique Identifier (UUID) or, equivalently, a Globally Unique
// Identifier (GUID) is a 128-bit identifier. UUIDs can be independently
// generated while having strong guarantees that no two generated UUIDs will
// have the same value.
// The format and algorithm for generating UUID is described in RFC 4122.
class Uuid {
// Generate the empty UUID ("00000000-0000-0000-0000-000000000000").
constexpr Uuid() : raw_{} {}
// Generate a UUID from the given 16-byte array.
// We assume that the buffer is stored in host-native endian order.
explicit Uuid(const uint8_t* buffer) { memcpy(&raw_, buffer, kUuidSize); }
// Generate a UUID from a RawUuid.
constexpr explicit Uuid(RawUuid raw) : raw_(raw) {}
// Generate a UUID from the given 16 bytes.
// This constructor can be used to generate compile-time constant UUIDs:
// constexpr Uuid kMyUuid = {0x01, 0x02, 0x03, 0x04, 0x04, 0x05, 0x06, 0x07,
// 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
// The input bytes are assumed to be in host-native endian format.
constexpr Uuid(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6,
uint8_t b7, uint8_t b8, uint8_t b9, uint8_t b10, uint8_t b11, uint8_t b12,
uint8_t b13, uint8_t b14, uint8_t b15)
: bytes_{b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15} {}
// Generate a new v4 UUID.
// This method generates a version 4 (random) UUID, using 122 bits of entropy
// provided by the kernel. The algorithm is described in RFC 4122,
// section 4.4.
static Uuid Generate();
// Generate a string representation of this UUID. The returned string will
// be of the form:
// 00112233-4455-6677-8899-aabbccddeeff
std::string ToString() const;
// Raw bytes of the UUID, in host-endian format.
const uint8_t* bytes() const { return bytes_; }
// Raw fields of the UUID.
const RawUuid& raw() const { return raw_; }
union {
RawUuid raw_;
uint8_t bytes_[kUuidSize];
static_assert(sizeof(Uuid) == kUuidSize);
// Equality / inequality.
inline bool operator==(const Uuid& a, const Uuid& b) {
return memcmp(a.bytes(), b.bytes(), kUuidSize) == 0;
inline bool operator!=(const Uuid& a, const Uuid& b) { return !(a == b); }
// Writes Uuid.ToString() to the given stream.
std::ostream& operator<<(std::ostream& out, const Uuid& uuid);
// Generate a 128-bit (pseudo) random UUID in the form of version 4 as described
// in RFC 4122, section 4.4.
// The format of UUID version 4 must be xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx,
// where y is one of [8, 9, A, B].
// The hexadecimal values "a" through "f" are output as lower case characters.
std::string Generate();
// Returns true if the input string conforms to the version 4 UUID format.
// Note that this does NOT check if the hexadecimal values "a" through "f"
// are in lower case characters, as Version 4 RFC says they're
// case insensitive. (Use IsValidOutputString for checking if the
// given string is valid output string)
bool IsValid(const std::string& guid);
// Returns true if the input string is valid version 4 UUID output string.
// This also checks if the hexadecimal values "a" through "f" are in lower
// case characters.
bool IsValidOutputString(const std::string& guid);
} // namespace uuid
#endif // SRC_LIB_UUID_UUID_H_