#include #include #include "uniqid.h" #include "atomic.h" #include "spinlock/spinlock.h" #include "hal/hal.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 uniqseed(void) { if (uniqstate != 0u) return; uint32_t seed = 0; int32_t r = hal_randnum(); if (r != -1) { seed = (uint32_t)r; } else { uintptr_t p = (uintptr_t)(void *)&uniqstate; seed = (uint32_t)(p ^ (p>>32)) ^ 0x9E3779B9u; } uniqstate = seed ? seed : 1u; } void randcrypto_gen_uniqid(char *out, size_t n) { if (!out || n == 0) { return; } spinlock_acquire(&uniqstate_spinlock); uniqseed(); int32_t r = hal_randnum(); uint32_t extra = (r != -1) ? (uint32_t)r : uniqstate * 0x27d4eb2dU; uniqstate += 0x9E3779B1u; uint32_t v = uniqmix32(uniqstate); spinlock_release(&uniqstate_spinlock); for (size_t i = 0; i < n; i++) { v = uniqmix32(v + i * 0x85ebca6bU); out[i] = base62[v % 62u]; } out[n] = '\0'; }