Skip to content

Instantly share code, notes, and snippets.

@LiosK
Last active April 3, 2024 02:11
Show Gist options
  • Save LiosK/2d81dc4d2ee614c1ade5f38ca6e2e3de to your computer and use it in GitHub Desktop.
Save LiosK/2d81dc4d2ee614c1ade5f38ca6e2e3de to your computer and use it in GitHub Desktop.
UUIDv8 Example
#include <stdint.h>
#include <time.h>
int get_random_bytes(uint8_t *buffer, int count);
int generate_uuidv8(uint8_t *uuid, uint8_t node_id) {
struct timespec tp;
if (clock_gettime(CLOCK_REALTIME, &tp) != 0)
return -1; // real-time clock error
// 32-bit biased timestamp (seconds elapsed since 2020-01-01 00:00:00 UTC)
uint32_t timestamp_sec = tp.tv_sec - 1577836800;
uuid[0] = timestamp_sec >> 24;
uuid[1] = timestamp_sec >> 16;
uuid[2] = timestamp_sec >> 8;
uuid[3] = timestamp_sec;
// 16-bit subsecond fraction (~15 microsecond resolution)
uint16_t timestamp_subsec = ((uint64_t)tp.tv_nsec << 16) / 1000000000;
uuid[4] = timestamp_subsec >> 8;
uuid[5] = timestamp_subsec;
// 58-bit random number and required ver and var fields
if (get_random_bytes(&uuid[6], 8) != 0)
return -1; // random number generator error
uuid[6] = 0x80 | (uuid[6] & 0x0f);
uuid[8] = 0x80 | (uuid[8] & 0x3f);
// 8-bit application-specific node ID to guarantee application-wide uniqueness
uuid[14] = node_id;
// 8-bit rolling sequence number to help ensure process-wide uniqueness
static uint8_t sequence = 0;
uuid[15] = sequence++; // NOTE: unprotected from race conditions
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int get_random_bytes(uint8_t *buffer, int count) {
arc4random_buf(buffer, count);
return 0;
}
int main(void) {
uint8_t uuid[16];
for (int i = 0; i < 8; i++) {
generate_uuidv8(uuid, 0x42);
for (int i = 0; i < 16; i++) {
printf("%02x", uuid[i]);
if (i == 3 || i == 5 || i == 7 || i == 9)
printf("-");
}
printf("\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment