static char *
generate_pseudo_uuid()
{
- static int init = 0;
-
- const char uuid_fmt[] = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
- const char uuid_chr[] = "0123456789ABCDEF-";
char *uuid;
- int i;
+ uint32_t rnd[4] = { 0, 0, 0, 0 };
+ uint64_t last = 0;
+ int byte = 0;
+ uint8_t bits = 0;
+ unsigned int rand_max_bits = my_flsl(RAND_MAX);
- if ((uuid = calloc(1, sizeof(uuid_fmt))) == NULL)
+ if ((uuid = calloc(1, 37)) == NULL)
return NULL;
- if (!init) {
- srand(now_ms * pid);
- init = 1;
- }
-
- for (i = 0; i < sizeof(uuid_fmt)-1; i++) {
- int r = rand () % 16;
-
- switch (uuid_fmt[i]) {
- case 'x' : uuid[i] = uuid_chr[r]; break;
- case 'y' : uuid[i] = uuid_chr[(r & 0x03) | 0x08]; break;
- default : uuid[i] = uuid_fmt[i]; break;
+ while (byte < 4) {
+ while (bits < 32) {
+ last |= (uint64_t)random() << bits;
+ bits += rand_max_bits;
}
- }
+ rnd[byte++] = last;
+ last >>= 32u;
+ bits -= 32;
+ }
+ snprintf(uuid, 36, "%8.8x-%4.4x-%4.4x-%4.4x-%12.12llx",
+ rnd[0],
+ rnd[1] & 0xFFFF,
+ ((rnd[1] >> 16u) & 0xFFF) | 0x4000, // highest 4 bits indicate the uuid version
+ (rnd[2] & 0x3FFF) | 0x8000, // the highest 2 bits indicate the UUID variant (10),
+ (long long)((rnd[2] >> 14u) | ((uint64_t) rnd[3] << 18u)) & 0xFFFFFFFFFFFFull
+ );
return uuid;
}
struct spoe_agent *agent = conf->agent;
if (agent->engine_id == NULL) {
+ srandom(now_ms * pid);
agent->engine_id = generate_pseudo_uuid();
if (agent->engine_id == NULL)
return -1;