summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2020-06-06 14:47:45 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2020-06-06 15:01:19 +0200
commitc00945ec1e5804003fb47798e86cd0c737a14d46 (patch)
tree06fa802760dcfb041d0ff0eda22cd9a1e661dc49 /src
parentfd04142b2accb08ab3c79bfd5c5bffd25b3f5784 (diff)
UUID: random generation and format checking functions
Diffstat (limited to 'src')
-rw-r--r--src/uuid.cpp47
1 files changed, 39 insertions, 8 deletions
diff --git a/src/uuid.cpp b/src/uuid.cpp
index 9af32b7..a53bf27 100644
--- a/src/uuid.cpp
+++ b/src/uuid.cpp
@@ -2,8 +2,12 @@
#include <stdexcept>
+#include <openssl/rand.h>
+
using namespace erebos;
+using std::nullopt;
+using std::optional;
using std::runtime_error;
using std::string;
@@ -12,15 +16,9 @@ static const size_t UUID_STR_LEN = 36;
static const char * FORMAT_STRING = "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-"
"%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx";
-UUID::UUID(string str)
+UUID::UUID(const string & str)
{
- if (str.size() != UUID_STR_LEN)
- throw runtime_error("invalid UUID");
-
- if (sscanf(str.c_str(), FORMAT_STRING,
- &uuid[0], &uuid[1], &uuid[2], &uuid[3], &uuid[4], &uuid[5], &uuid[6], &uuid[7],
- &uuid[8], &uuid[9], &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15])
- != 16)
+ if (!fromString(str, *this))
throw runtime_error("invalid UUID");
}
@@ -33,6 +31,39 @@ UUID::operator string() const
return str;
}
+optional<UUID> UUID::fromString(const string & str)
+{
+ UUID u;
+ if (fromString(str, u))
+ return u;
+ return nullopt;
+}
+
+bool UUID::fromString(const string & str, UUID & u)
+{
+ if (str.size() != UUID_STR_LEN)
+ return false;
+
+ if (sscanf(str.c_str(), FORMAT_STRING,
+ &u.uuid[0], &u.uuid[1], &u.uuid[2], &u.uuid[3], &u.uuid[4], &u.uuid[5], &u.uuid[6], &u.uuid[7],
+ &u.uuid[8], &u.uuid[9], &u.uuid[10], &u.uuid[11], &u.uuid[12], &u.uuid[13], &u.uuid[14], &u.uuid[15])
+ != 16)
+ return false;
+
+ return true;
+}
+
+UUID UUID::generate()
+{
+ UUID u;
+ if (RAND_bytes(u.uuid.data(), u.uuid.size()) != 1)
+ throw runtime_error("failed to generate random UUID");
+
+ u.uuid[6] = (u.uuid[6] & 0x0f) | 0x40;
+ u.uuid[8] = (u.uuid[8] & 0x3f) | 0x80;
+ return u;
+}
+
bool UUID::operator==(const UUID & other) const
{
return std::equal(std::begin(uuid), std::end(uuid), std::begin(other.uuid));