From ebfc4413323e128abadfa5b6e46797a13adcf5ad Mon Sep 17 00:00:00 2001 From: Jared Shi <119568837+jaredshi0@users.noreply.github.com> Date: Thu, 26 Dec 2024 05:31:06 -0500 Subject: [PATCH] feat: add uuidv7 functions (#1020) * added uuidv7 * fix format * removed todo comments --- src/modules/string.cpp | 39 ++++++++++++++++++++++++++++++++--- tests/modules/string_test.cpp | 35 +++++++++++++++++++------------ 2 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/modules/string.cpp b/src/modules/string.cpp index 12d515f3..eddabac1 100644 --- a/src/modules/string.cpp +++ b/src/modules/string.cpp @@ -584,6 +584,41 @@ std::string uuidV6() return ss.str(); } +std::string uuidV7() +{ + RandomGenerator gen = RandomGenerator{}; + auto now = std::chrono::system_clock::now(); + auto since_epoch = now.time_since_epoch(); + + const auto timestamp = + static_cast(std::chrono::duration_cast(since_epoch).count()); + + const auto time_high = static_cast((timestamp >> 16) & 0xFFFFFFFFULL); + const auto time_low = static_cast(timestamp & 0xFFFFULL); + + std::uniform_int_distribution rand_a_seq_dis(0, 0xFFF); + uint16_t rand_a_seq = (gen(rand_a_seq_dis) & 0xFFF); + rand_a_seq |= 0x7000; + + std::uniform_int_distribution rand_b_seq_dis(0, 0xFFFFFFFFULL); + uint64_t rand_b_seq = static_cast(gen(rand_b_seq_dis)); + rand_b_seq = rand_b_seq << 32; + rand_b_seq |= static_cast(gen(rand_b_seq_dis)); + + uint16_t rand_b_high = ((rand_b_seq >> 32) & 0x3FFFULL) | 0x8000; + uint64_t rand_b_low = (rand_b_seq & 0xFFFFFFFFFFFFULL); + + std::ostringstream ss; + ss << std::hex << std::setfill('0'); + ss << std::setw(8) << time_high << '-'; + ss << std::setw(4) << time_low << '-'; + ss << std::setw(4) << rand_a_seq << '-'; + ss << std::setw(4) << rand_b_high << '-'; + ss << std::setw(12) << rand_b_low; + + return ss.str(); +} + std::string uuid(Uuid uuid, const std::string& namespace_uuid, const std::string& name) { switch (uuid) @@ -598,11 +633,9 @@ std::string uuid(Uuid uuid, const std::string& namespace_uuid, const std::string // TODO: implement uuidV5 return uuidV5(namespace_uuid, name); case Uuid::V6: - // TODO: implement uuidV6 return uuidV6(); case Uuid::V7: - // TODO: implement uuidV7 - return uuidV4(); + return uuidV7(); case Uuid::V8: // TODO: implement uuidV8 return uuidV4(); diff --git a/tests/modules/string_test.cpp b/tests/modules/string_test.cpp index 866aace6..e8322666 100644 --- a/tests/modules/string_test.cpp +++ b/tests/modules/string_test.cpp @@ -69,40 +69,49 @@ TEST_F(StringTest, shouldGenerateUuid4Default) ASSERT_EQ(generatedUuid[18], '-'); ASSERT_EQ(generatedUuid[23], '-'); } -TEST_F(StringTest, shouldGenerateUuid5) { + +TEST_F(StringTest, shouldGenerateUuid5) +{ const std::string namespaceUuid = "6ba7b810-9dad-11d1-80b4-00c04fd430c8"; const std::string name = "example_name"; - const auto generatedUuid = uuid(Uuid::V5,namespaceUuid, name); + const auto generatedUuid = uuid(Uuid::V5, namespaceUuid, name); std::cerr << "Generated UUID: " << generatedUuid << std::endl; // Ensure the UUID has the correct format - ASSERT_EQ(generatedUuid.size(), 36); // UUIDs must be 36 characters including hyphens - ASSERT_EQ(generatedUuid[8], '-'); // Hyphen at position 8 - ASSERT_EQ(generatedUuid[13], '-'); // Hyphen at position 13 - ASSERT_EQ(generatedUuid[18], '-'); // Hyphen at position 18 - ASSERT_EQ(generatedUuid[23], '-'); // Hyphen at position 23 - - + ASSERT_EQ(generatedUuid.size(), 36); // UUIDs must be 36 characters including hyphens + ASSERT_EQ(generatedUuid[8], '-'); // Hyphen at position 8 + ASSERT_EQ(generatedUuid[13], '-'); // Hyphen at position 13 + ASSERT_EQ(generatedUuid[18], '-'); // Hyphen at position 18 + ASSERT_EQ(generatedUuid[23], '-'); // Hyphen at position 23 } -TEST_F(StringTest, shouldGenerateUuid6) { +TEST_F(StringTest, shouldGenerateUuid6) +{ const auto generatedUuid = uuid(Uuid::V6); std::cerr << "Generated UUID: " << generatedUuid << std::endl; - - // Ensure the UUID has the correct format ASSERT_EQ(generatedUuid.size(), 36); ASSERT_EQ(generatedUuid[8], '-'); ASSERT_EQ(generatedUuid[13], '-'); ASSERT_EQ(generatedUuid[18], '-'); ASSERT_EQ(generatedUuid[23], '-'); +} +TEST_F(StringTest, shouldGenerateUuid7) +{ + const auto generatedUuid = uuid(Uuid::V7); + // Ensure the UUID has the correct format + ASSERT_EQ(generatedUuid.size(), 36); + ASSERT_EQ(generatedUuid[8], '-'); + ASSERT_EQ(generatedUuid[13], '-'); + ASSERT_EQ(generatedUuid[18], '-'); + ASSERT_EQ(generatedUuid[23], '-'); + ASSERT_EQ(generatedUuid[14], '7'); } - TEST_F(StringTest, shouldGenerateUlidNoArguments) { const auto generatedUlidNoArg = ulid();