#include #include #include "uniqid.h" #include "atomic.h" #include "spinlock/spinlock.h" static const char *base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static uint32_t uniqstate = 0u; SpinLock uniqstate_spinlock; void randcrypto_uniqid_init(void) { spinlock_init(&uniqstate_spinlock); } uint32_t uniqmix32(uint32_t x) { x ^= x >> 16; x *= 0x85ebca6bU; x ^= x >> 13; x *= 0xc2b2ae35U; x ^= x >> 16; return x; } void randcrypto_gen_uniqid(char *out, size_t n) { if (!out || n == 0) { return; } spinlock_acquire(&uniqstate_spinlock); if (uniqstate == 0u) { uintptr_t p = (uintptr_t)(void *)&uniqstate; uint32_t seed = (uint32_t)(p ^ (p >> 16)); uniqstate = seed ^ 0x9E3779B9u; if (uniqstate == 0u) { uniqstate = 1u; } } uniqstate += 0x9E3779B1u; uint32_t v = uniqmix32(uniqstate); spinlock_release(&uniqstate_spinlock); for (size_t i = 0; i < n; i++) { v = uniqmix32(v + i * 0x27d4eb2dU); out[i] = base62[v % 62u]; } out[n] = '\0'; }