2022-06-14 09:20:04 -04:00
|
|
|
//
|
|
|
|
// FILE: UUID.cpp
|
|
|
|
// AUTHOR: Rob Tillaart
|
2022-06-16 03:37:59 -04:00
|
|
|
// VERSION: 0.1.3
|
2022-06-14 09:20:04 -04:00
|
|
|
// DATE: 2022-06-14
|
|
|
|
// PURPOSE: Arduino Library for generating UUID's
|
|
|
|
// URL: https://github.com/RobTillaart/UUID
|
2022-06-15 01:34:09 -04:00
|
|
|
// https://en.wikipedia.org/wiki/Universally_unique_identifier
|
2022-06-14 09:20:04 -04:00
|
|
|
//
|
|
|
|
// HISTORY
|
|
|
|
// 0.1.0 2022-06-14 initial version
|
2022-06-15 01:34:09 -04:00
|
|
|
// 0.1.1 2022-06-15 improve performance generate()
|
|
|
|
// minor edits in readme.md
|
|
|
|
// fix bug in generator
|
|
|
|
// define UUID_MODE_VARIANT4
|
|
|
|
// define UUID_MODE_RANDOM
|
2022-06-16 03:37:59 -04:00
|
|
|
// 0.1.2 2022-06-15 fix version number
|
2022-06-15 04:31:57 -04:00
|
|
|
// improve performance generate()
|
2022-06-16 03:37:59 -04:00
|
|
|
// 0.1.3 2022-06-16 improve performance generate() again
|
2022-06-14 09:20:04 -04:00
|
|
|
|
|
|
|
|
|
|
|
#include "UUID.h"
|
|
|
|
|
|
|
|
|
|
|
|
UUID::UUID()
|
|
|
|
{
|
|
|
|
seed(1, 2);
|
2022-06-15 01:34:09 -04:00
|
|
|
setVariant4Mode();
|
2022-06-14 09:20:04 -04:00
|
|
|
generate();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void UUID::seed(uint32_t s1, uint32_t s2)
|
|
|
|
{
|
|
|
|
// set Marsaglia constants, prevent 0 as value
|
|
|
|
if (s1 == 0) s1 = 1;
|
|
|
|
if (s2 == 0) s2 = 2;
|
|
|
|
_m_w = s1;
|
|
|
|
_m_z = s2;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-06-15 04:31:57 -04:00
|
|
|
// check version 0.1.1 for more readable code
|
2022-06-14 09:20:04 -04:00
|
|
|
void UUID::generate()
|
|
|
|
{
|
|
|
|
uint32_t _ar[4];
|
|
|
|
for (uint8_t i = 0; i < 4; i++)
|
|
|
|
{
|
|
|
|
_ar[i] = _random();
|
|
|
|
}
|
2022-06-15 01:34:09 -04:00
|
|
|
|
|
|
|
// patch bits for version 1 and variant 4 here
|
|
|
|
if (_mode == UUID_MODE_VARIANT4)
|
|
|
|
{
|
|
|
|
_ar[1] &= 0xFFF0FFFF; // remove 4 bits.
|
|
|
|
_ar[1] |= 0x00040000; // variant 4
|
|
|
|
_ar[2] &= 0xFFFFFFF3; // remove 2 bits
|
|
|
|
_ar[2] |= 0x00000008; // version 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// store globally ?
|
|
|
|
|
2022-06-15 04:31:57 -04:00
|
|
|
// process 16 bytes build up the char array.
|
|
|
|
for (uint8_t i = 0, j = 0; i < 16; i++)
|
2022-06-14 09:20:04 -04:00
|
|
|
{
|
2022-06-15 04:31:57 -04:00
|
|
|
// multiples of 4 between 8 and 20 get a -.
|
|
|
|
// but note we are doing 2 digits in one loop.
|
|
|
|
if ((i & 0x1) == 0)
|
|
|
|
{
|
|
|
|
if ((4 <= i) && (i <= 10)) _buffer[j++] = '-';
|
|
|
|
}
|
|
|
|
|
|
|
|
// process one byte at the time instead of a nibble
|
|
|
|
uint8_t nr = i / 4;
|
2022-06-16 03:37:59 -04:00
|
|
|
uint8_t xx = _ar[nr];
|
|
|
|
uint8_t ch = xx & 0xF;
|
|
|
|
_buffer[j++] = (ch < 10) ? '0' + ch : ('a' - 10) + ch;
|
2022-06-15 04:31:57 -04:00
|
|
|
|
2022-06-16 03:37:59 -04:00
|
|
|
ch = (xx >> 4) & 0xF;
|
2022-06-15 04:31:57 -04:00
|
|
|
_ar[nr] >>= 8;
|
2022-06-16 03:37:59 -04:00
|
|
|
_buffer[j++] = (ch < 10) ? '0' + ch : ('a' - 10) + ch;
|
2022-06-14 09:20:04 -04:00
|
|
|
}
|
|
|
|
_buffer[36] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
char * UUID::toCharArray()
|
|
|
|
{
|
|
|
|
return _buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// PRINTING
|
|
|
|
size_t UUID::printTo(Print& p) const
|
|
|
|
{
|
|
|
|
return p.print(_buffer);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// An example of a simple pseudo-random number generator is the
|
|
|
|
// Multiply-with-carry method invented by George Marsaglia.
|
|
|
|
// two initializers (not null)
|
|
|
|
uint32_t UUID::_random()
|
|
|
|
{
|
|
|
|
_m_z = 36969L * (_m_z & 65535L) + (_m_z >> 16);
|
|
|
|
_m_w = 18000L * (_m_w & 65535L) + (_m_w >> 16);
|
|
|
|
return (_m_z << 16) + _m_w; /* 32-bit result */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// -- END OF FILE --
|
|
|
|
|