diff --git a/src/libs/utils/impl/UUID.cpp b/src/libs/utils/impl/UUID.cpp index 93f30d34..096ca0e5 100644 --- a/src/libs/utils/impl/UUID.cpp +++ b/src/libs/utils/impl/UUID.cpp @@ -19,40 +19,71 @@ #include "utils/UUID.hpp" +#include +#include #include +#include +#include "utils/Random.hpp" #include "utils/String.hpp" namespace StringUtils { - template <> - std::optional - readAs(std::string_view str) - { - return UUID::fromString(str); - } + template <> + std::optional + readAs(std::string_view str) + { + return UUID::fromString(str); + } } - -static -bool -stringIsUUID(std::string_view str) +namespace { - static const std::regex re { R"([0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12})"}; + bool stringIsUUID(std::string_view str) + { + static const std::regex re{ R"([0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12})" }; - return std::regex_match(std::cbegin(str), std::cend(str), re); + return std::regex_match(std::cbegin(str), std::cend(str), re); + } } UUID::UUID(std::string_view str) - : _value {StringUtils::stringToLower(str)} + : _value{ StringUtils::stringToLower(str) } { } -std::optional -UUID::fromString(std::string_view str) +std::optional UUID::fromString(std::string_view str) { - if (!stringIsUUID(str)) - return std::nullopt; + if (!stringIsUUID(str)) + return std::nullopt; - return UUID {str}; + return UUID{ str }; +} + +UUID UUID::generate() +{ + // Form is "123e4567-e89b-12d3-a456-426614174000" + // TODO: store 128 bits and only convert to string when necessary + + std::ostringstream oss; + + auto concatRandomBytes{ [](std::ostream& os, std::size_t byteCount) + { + for (std::size_t i {}; i < byteCount; ++i) + os << std::hex << std::setfill('0') << std::setw(2) << static_cast(Random::getRandom(0, 255)); + } }; + + concatRandomBytes(oss, 4); + oss << "-"; + concatRandomBytes(oss, 2); + oss << "-"; + concatRandomBytes(oss, 2); + oss << "-"; + concatRandomBytes(oss, 2); + oss << "-"; + concatRandomBytes(oss, 6); + + const auto uuid{fromString(oss.str())}; + assert(uuid); + return uuid.value(); } diff --git a/src/libs/utils/include/utils/UUID.hpp b/src/libs/utils/include/utils/UUID.hpp index 9d4ee2f2..2507965c 100644 --- a/src/libs/utils/include/utils/UUID.hpp +++ b/src/libs/utils/include/utils/UUID.hpp @@ -27,20 +27,21 @@ class UUID { - public: - static std::optional fromString(std::string_view str); +public: + static std::optional fromString(std::string_view str); + static UUID generate(); - std::string_view getAsString() const { return _value; } + std::string_view getAsString() const { return _value; } - private: - UUID(std::string_view value); - std::string _value; +private: + UUID(std::string_view value); + std::string _value; }; namespace StringUtils { - template <> - std::optional - readAs(std::string_view str); + template <> + std::optional + readAs(std::string_view str); }