Skip to content

Instantly share code, notes, and snippets.

@puppy0cam
Last active December 14, 2019 00:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save puppy0cam/b4cfc49e6b0da893323fdfc664c69eef to your computer and use it in GitHub Desktop.
Save puppy0cam/b4cfc49e6b0da893323fdfc664c69eef to your computer and use it in GitHub Desktop.
UUID v4 generator. The project was used to help me teach myself the basics of C++, and eventually I went heavily into trying to optimise it.
#pragma once
#include "GenerateUUID.h"
#ifndef UUID_CHARACTER_COUNT
#define UUID_CHARACTER_COUNT 36
#endif
#include "GenerateUUIDString.cpp"
#include <string>
// Generates a UUID v4 string.
// Memory collection is handled automatically for this string.
std::string GenerateUUID() {
const char *uuid = GenerateUUIDString();
std::string result = std::string(uuid, UUID_CHARACTER_COUNT);
delete uuid;
return result;
}
#pragma once
#include <string>
#include "GenerateUUIDString.h"
std::string GenerateUUID();
#pragma once
#include "GenerateUUIDString.h"
#ifndef UUID_CHARACTER_COUNT
#define UUID_CHARACTER_COUNT 36
#endif
#include "GetUUIDCharacterForPosition.cpp"
// generates a UUID v4 string.
// When done with value, remember to delete the pointed value.
const char *GenerateUUIDString() {
char *result = new char[UUID_CHARACTER_COUNT];
for (unsigned char i = 0; i < UUID_CHARACTER_COUNT; i++) {
#ifdef UUID_OPTIMISED_CHARACTER_GENERATION
result[i] = GetUUIDCharacterForPosition();
#else
result[i] = GetUUIDCharacterForPosition(i);
#endif
}
return result;
}
#pragma once
#include "GetUUIDCharacterForPosition.h"
// generates a UUID v4 string.
// When done with value, remember to delete the pointed value.
const char *GenerateUUIDString();
#pragma once
#include "GetCharacterForHexByteOffset.h"
// takes the hex value and converts it into the appropriate hex character
const char GetCharacterForHexByteOffset(const unsigned char value) {
if (value < 10) {
return value + 48;
} else {
return value + 87;
}
}
#pragma once
// takes the hex value and converts it into the appropriate hex character
const char GetCharacterForHexByteOffset(const unsigned char value);
#pragma once
#include "GetUUIDCharacterForPosition.h"
#include "RandomByte.cpp"
#include "GetCharacterForHexByteOffset.cpp"
// Returns a character relevant to a UUID generation instance
const char GetUUIDCharacterForPosition() {
return GetCharacterForHexByteOffset(RandomByte::GetRandomHexPosition());
}
// Returns a character relevant to a UUID generation instance
const char GetUUIDCharacterForPosition(const unsigned char position) {
switch (position) {
default:
return GetCharacterForHexByteOffset(RandomByte::GetRandomHexPosition());
#ifndef UUID_DISABLE_DASHES
case 8:
case 13:
case 18:
case 23:
return '-';
#endif
#ifndef UUID_DISABLE_VERSION_CHARACTERS
case 14:
return '4';
case 19:
return GetCharacterForHexByteOffset(RandomByte::GetRandomHexPosition() / 4 + 8);
#endif
}
}
#pragma once
#include "RandomByte.h"
#include "GetCharacterForHexByteOffset.h"
// Returns a character relevant to a UUID generation instance
const char GetUUIDCharacterForPosition();
// Returns a character relevant to a UUID generation instance
const char GetUUIDCharacterForPosition(const unsigned char position);
#pragma once
#include "RandomByte.h"
#include <random>
// gets a random between 0-15 to be converted by GetCharacterForHexByteOffset
const unsigned char RandomByte::GetRandomHexPosition() {
if (RandomByte::hex_state = !RandomByte::hex_state) {
return RandomByte::data[RandomByte::position] % 16;
} else if (RandomByte::position == sizeof(unsigned int)) {
RandomByte::value = RandomByte::rng();
return RandomByte::data[RandomByte::position = 0] / 16;
} else {
return RandomByte::data[RandomByte::position++] / 16;
}
}
#pragma once
#include <random>
// Area to get random data for UUID generation
namespace RandomByte {
// random number generation
std::random_device rng;
// value to infer bytes from
unsigned int value = rng();
// which byte of the random value to access.
// Starts at -1 as usagee is incremented before usage
unsigned char position = 0;
// variable for accessing the value from
const unsigned char *data = (const unsigned char *)&value;
// simple bool to decide which operation should be used to infer a random hex value
bool hex_state = false;
// gets a random between 0-15 to be converted by GetCharacterForHexByteOffset
const unsigned char GetRandomHexPosition();
}
#pragma once
#include "RunPerformanceTestOnUUID.h"
#ifdef UUID_ENABLE_PERFORMANCE_TEST_FUNCTION
#include <chrono>
#include "GenerateUUID.cpp"
#include <string>
long long RunPerformanceTestOnUUID(const unsigned long long iterations) {
std::chrono::time_point<std::chrono::steady_clock> start = std::chrono::steady_clock::now();
for (unsigned long long i = 0; i < iterations; i++) {
std::string uuid = GenerateUUID();
}
std::chrono::time_point<std::chrono::steady_clock> end = std::chrono::steady_clock::now();
return std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
}
#endif
#pragma once
#ifdef UUID_ENABLE_PERFORMANCE_TEST_FUNCTION
#include <chrono>
#include "GenerateUUID.h"
#include <string>
long long RunPerformanceTestOnUUID(const unsigned long long iterations);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment