enum {ulid_byte_len=26}; /** * Generate a ULID (Universally Unique Lexicographically Sortable Identifier) * Returns str given arena. * * ULID format: 26 characters (Crockford Base32). * - 48 bits = milliseconds since Unix epoch (6 bytes, big‑endian) * - 80 bits = random data (10 bytes) * */ static str generate_ulid(arena *A) { // Crockford Base32 alphabet (no I, L, O, U) static const char ALPHABET[] = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; // 1. Get current time in milliseconds struct timespec ts; if (clock_gettime(CLOCK_REALTIME, &ts) != 0) return (str){0}; uint64_t ms = (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; // 2. Generate 10 random bytes (80 bits) uint8_t random_bytes[10]; #if defined(__APPLE__) || defined(__FreeBSD__) arc4random_buf(random_bytes, sizeof(random_bytes)); #else int fd = open("/dev/urandom", O_RDONLY); if (fd < 0) return (str){0}; ssize_t n = read(fd, random_bytes, sizeof(random_bytes)); close(fd); if (n != sizeof(random_bytes)) return (str){0}; #endif // 3. Build the 16‑byte ULID payload (big‑endian timestamp + random) uint8_t payload[16]; // Timestamp (6 bytes, most significant byte first) for (int i = 0; i < 6; i++) { payload[5 - i] = (uint8_t)(ms & 0xFF); ms >>= 8; } // Random part memcpy(payload + 6, random_bytes, 10); // 4. Encode to 26 Base32 characters (Crockford) int bit_buf = 0; int bit_cnt = 0; int out_pos = 0; uint8_t *encoded = new(A, uint8_t, ulid_byte_len); encoded[0]=0; for (int i = 0; i < 16; i++) { // Feed the payload byte by byte bit_buf = (bit_buf << 8) | payload[i]; bit_cnt += 8; while (bit_cnt >= 5 && out_pos < ulid_byte_len) { // Extract top 5 bits int idx = (bit_buf >> (bit_cnt - 5)) & 0x1F; encoded[out_pos++] = ALPHABET[idx]; bit_cnt -= 5; } } // Flush any remaining bits (should be exactly 3 bits for ULID) if (bit_cnt > 0 && out_pos < ulid_byte_len) { int idx = (bit_buf << (5 - bit_cnt)) & 0x1F; encoded[out_pos++] = ALPHABET[idx]; } return str_from_buf(encoded, ulid_byte_len); }