Skip to content

Commit

Permalink
uuid-v3
Browse files Browse the repository at this point in the history
  • Loading branch information
Cobollatin committed Nov 30, 2024
1 parent bdc9095 commit 0422b1e
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 11 deletions.
45 changes: 42 additions & 3 deletions include/faker-cxx/string.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#pragma once

#include <algorithm>
#include <array>
#include <chrono>
#include <cstdint>
#include <cstring>
#include <iomanip>
#include <limits>
#include <map>
Expand Down Expand Up @@ -112,6 +116,34 @@ std::string uuidV1(RandomGenerator<T> gen = RandomGenerator<T>{})
return ss.str();
}

template <typename T = std::mt19937>
std::string uuidV3(RandomGenerator<T> gen = RandomGenerator<T>{})
{
// FAking MD5 hash with random data from the generator is enough for this purpose
std::array<uint8_t, 16> hash;
std::uniform_int_distribution<int> dist(0, 255);

for (auto& byte : hash)
{
byte = gen(dist);
}

hash[6] = (hash[6] & 0x0F) | 0x30; // Set the version to 3
hash[8] = (hash[8] & 0x3F) | 0x80; // Set the variant to '10'

std::ostringstream ss;
ss << std::hex << std::setfill('0');
for (size_t i = 0; i < hash.size(); ++i)
{
ss << std::setw(2) << static_cast<int>(hash[i]);
// Add hyphens at the appropriate positions
if (i == 3 || i == 5 || i == 7 || i == 9)
ss << '-';
}

return ss.str();
}

template <typename T = std::mt19937>
std::string uuidV4(RandomGenerator<T> gen = RandomGenerator<std::mt19937>{})
{
Expand Down Expand Up @@ -167,7 +199,7 @@ std::string uuidV4(RandomGenerator<T> gen = RandomGenerator<std::mt19937>{})
* @returns UUID.
*
* @code
* faker::string::uuid() // "27666229-cedb-4a45-8018-98b1e1d921e2"
* faker::string::uuid() // V4: "27666229-cedb-4a45-8018-98b1e1d921e2"
* @endcode
*/
template <typename T = std::mt19937>
Expand All @@ -184,7 +216,14 @@ std::string uuid(RandomGenerator<T> gen)
* @returns UUID.
*
* @code
* faker::string::uuid() // "27666229-cedb-4a45-8018-98b1e1d921e2"
* faker::string::uuid() // "27666229-cedb-4a45-8018-98b1e1d921e2" // V4
* faker::string::uuid(Uuid::V1) // "04f916a0-af32-11ef-9cd2-0242ac120002"
* faker::string::uuid(Uuid::V3) // "a3bb189e-8bf9-3888-9912-ace4e6543002"
* faker::string::uuid(Uuid::V4) // "27666229-cedb-4a45-8018-98b1e1d921e2"
* faker::string::uuid(Uuid::V5) // "27666229-cedb-4a45-8018-98b1e1d921e2"
* faker::string::uuid(Uuid::V6) // "27666229-cedb-4a45-8018-98b1e1d921e2"
* faker::string::uuid(Uuid::V7) // "27666229-cedb-4a45-8018-98b1e1d921e2"
* faker::string::uuid(Uuid::V8) // "27666229-cedb-4a45-8018-98b1e1d921e2"
* @endcode
*/
template <typename T = std::mt19937>
Expand All @@ -195,7 +234,7 @@ std::string uuid(Uuid uuid = Uuid::V4, RandomGenerator<T> gen = RandomGenerator<
case Uuid::V1:
return uuidV1(gen);
case Uuid::V3:
return uuidV4(gen);
return uuidV3(gen);
case Uuid::V4:
return uuidV4(gen);
case Uuid::V5:
Expand Down
44 changes: 36 additions & 8 deletions tests/modules/string_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,44 @@ TEST_F(StringTest, shouldGenerateUuid1)
ASSERT_EQ(generatedUuid[18], '-');
ASSERT_EQ(generatedUuid[23], '-');

// Check the version number
ASSERT_EQ(generatedUuid[14], '1');
}

TEST_F(StringTest, shouldUseCustomRandomGeneratorForUuid3)
{
RandomGenerator<std::mt19937> gen1{};
const auto generatedUuid1 = uuid(Uuid::V3, gen1);

ASSERT_EQ(generatedUuid1.size(), 36);
ASSERT_EQ(generatedUuid1[8], '-');
ASSERT_EQ(generatedUuid1[13], '-');
ASSERT_EQ(generatedUuid1[18], '-');
ASSERT_EQ(generatedUuid1[23], '-');
ASSERT_EQ(generatedUuid1[14], '3'); // Check for version 3

// Check that the variant bits are '10'
char clock_seq_hi_and_reserved_char = generatedUuid[19];
int cshr_value = (clock_seq_hi_and_reserved_char >= '0' && clock_seq_hi_and_reserved_char <= '9') ?
clock_seq_hi_and_reserved_char - '0' :
clock_seq_hi_and_reserved_char - 'a' + 10;
ASSERT_TRUE((cshr_value & 0x8) != 0); // Bit 7 should be 1
ASSERT_TRUE((cshr_value & 0x4) == 0); // Bit 6 should be 0
RandomGenerator<std::mt19937_64> gen2{};
const auto generatedUuid2 = uuid(Uuid::V3, gen2);

ASSERT_EQ(generatedUuid2.size(), 36);
ASSERT_EQ(generatedUuid2[8], '-');
ASSERT_EQ(generatedUuid2[13], '-');
ASSERT_EQ(generatedUuid2[18], '-');
ASSERT_EQ(generatedUuid2[23], '-');
ASSERT_EQ(generatedUuid2[14], '3');
}

TEST_F(StringTest, shouldGenerateUuid3)
{
const auto generatedUuid = uuid(Uuid::V3);

ASSERT_EQ(generatedUuid.size(), 36);
ASSERT_EQ(generatedUuid[8], '-');
ASSERT_EQ(generatedUuid[13], '-');
ASSERT_EQ(generatedUuid[18], '-');
ASSERT_EQ(generatedUuid[23], '-');

// Check the version number
ASSERT_EQ(generatedUuid[14], '3');
}

TEST_F(StringTest, shouldUseCustomRandomGeneratorForUuid4)
Expand Down

0 comments on commit 0422b1e

Please sign in to comment.