Make uniqids truly random
This commit is contained in:
@ -3,6 +3,7 @@
|
|||||||
#include "uniqid.h"
|
#include "uniqid.h"
|
||||||
#include "atomic.h"
|
#include "atomic.h"
|
||||||
#include "spinlock/spinlock.h"
|
#include "spinlock/spinlock.h"
|
||||||
|
#include "hal/hal.h"
|
||||||
|
|
||||||
static const char *base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
static const char *base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
@ -22,6 +23,22 @@ uint32_t uniqmix32(uint32_t x) {
|
|||||||
return x;
|
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) {
|
void randcrypto_gen_uniqid(char *out, size_t n) {
|
||||||
if (!out || n == 0) {
|
if (!out || n == 0) {
|
||||||
return;
|
return;
|
||||||
@ -29,14 +46,10 @@ void randcrypto_gen_uniqid(char *out, size_t n) {
|
|||||||
|
|
||||||
spinlock_acquire(&uniqstate_spinlock);
|
spinlock_acquire(&uniqstate_spinlock);
|
||||||
|
|
||||||
if (uniqstate == 0u) {
|
uniqseed();
|
||||||
uintptr_t p = (uintptr_t)(void *)&uniqstate;
|
|
||||||
uint32_t seed = (uint32_t)(p ^ (p >> 16));
|
int32_t r = hal_randnum();
|
||||||
uniqstate = seed ^ 0x9E3779B9u;
|
uint32_t extra = (r != -1) ? (uint32_t)r : uniqstate * 0x27d4eb2dU;
|
||||||
if (uniqstate == 0u) {
|
|
||||||
uniqstate = 1u;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uniqstate += 0x9E3779B1u;
|
uniqstate += 0x9E3779B1u;
|
||||||
uint32_t v = uniqmix32(uniqstate);
|
uint32_t v = uniqmix32(uniqstate);
|
||||||
@ -44,7 +57,7 @@ void randcrypto_gen_uniqid(char *out, size_t n) {
|
|||||||
spinlock_release(&uniqstate_spinlock);
|
spinlock_release(&uniqstate_spinlock);
|
||||||
|
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
v = uniqmix32(v + i * 0x27d4eb2dU);
|
v = uniqmix32(v + i * 0x85ebca6bU);
|
||||||
out[i] = base62[v % 62u];
|
out[i] = base62[v % 62u];
|
||||||
}
|
}
|
||||||
out[n] = '\0';
|
out[n] = '\0';
|
||||||
|
|||||||
Reference in New Issue
Block a user