Create a more random approach to uuid generation (#868)

* Create a more random approach to uuid generation
* Add two additional test cases for Uuid
This commit is contained in:
Rick Winter 2020-11-02 08:49:41 -08:00 committed by GitHub
parent 2f93294fb1
commit e099942e25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 4 deletions

View File

@ -21,7 +21,7 @@ namespace Azure { namespace Core {
class Uuid {
private:
static const int UuidSize = 16;
static constexpr int UuidSize = 16;
uint8_t m_uuid[UuidSize];
// The UUID reserved variants.
@ -74,12 +74,14 @@ namespace Azure { namespace Core {
static Uuid CreateUuid()
{
std::random_device rd;
std::mt19937 gen(rd());
uint8_t uuid[UuidSize] = {};
for (int i = 0; i < UuidSize; i += 4)
*reinterpret_cast<uint32_t*>(uuid + i) = gen();
{
const uint32_t x = rd();
std::memcpy(uuid + i, &x, 4);
}
// SetVariant to ReservedRFC4122
uuid[8] = (uuid[8] | ReservedRFC4122) & 0x7F;

View File

@ -4,7 +4,7 @@
#include "gtest/gtest.h"
#include <azure/core/uuid.hpp>
#include <string>
#include <vector>
#include <set>
using namespace Azure::Core;
@ -13,3 +13,60 @@ TEST(Uuid, Basic)
auto uuid = Uuid::CreateUuid();
EXPECT_TRUE(uuid.GetUuidString().length() == 36);
}
TEST(Uuid, Randomness)
{
const int size = 100000;
std::set<std::string> uuids;
for (int i = 0; i < size; i++)
{
auto ret = uuids.insert(Uuid::CreateUuid().GetUuidString());
//If the value already exists in the set then the insert will fail
// ret.second == false means the insert failed.
EXPECT_TRUE(ret.second);
}
EXPECT_TRUE(uuids.size() == size);
}
TEST(Uuid, separatorPosition)
{
auto uuidKey = Uuid::CreateUuid().GetUuidString();
// validate expected format '8-4-4-4-12'
EXPECT_PRED5(
[](std::string const& uuidKey, char pos1, char pos2, char pos3, char pos4) {
return pos1 == pos2 && pos1 == pos3 && pos1 == pos4 && pos1 == '-';
},
uuidKey,
uuidKey[8],
uuidKey[13],
uuidKey[18],
uuidKey[23]);
}
TEST(Uuid, validChars)
{
auto uuidKey = Uuid::CreateUuid().GetUuidString();
// validate valid chars and separators count
EXPECT_PRED2(
[](std::string const& uuidKey, int expectedSeparators) {
int separatorsCount = 0;
for (int index = 0; index < uuidKey.size(); index++)
{
if (uuidKey[index] == '-')
{
separatorsCount++;
continue;
}
else if (!((uuidKey[index] >= '0' && uuidKey[index] <= '9')
|| (uuidKey[index] >= 'a' && uuidKey[index] <= 'f')
|| (uuidKey[index] >= 'A' && uuidKey[index] <= 'F')))
{
// invalid char found
return false;
}
}
return separatorsCount == expectedSeparators;
},
uuidKey,
4);
}