Expose storedevs to the outside world via dev interface
This commit is contained in:
51
kernel/randcrypto/uniqid.c
Normal file
51
kernel/randcrypto/uniqid.c
Normal file
@ -0,0 +1,51 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#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';
|
||||
}
|
||||
Reference in New Issue
Block a user