mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-11 05:52:36 +02:00
libreboot-utils: tidy up rand
make it more efficient. much lower rejection rate now, about 2-5%. deal with bias, but also get numbers in bulk. not too many. i'd say this is about right in terms of performance balance. 64 bytes == 8 large integers. Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
@@ -879,33 +879,32 @@ err:
|
|||||||
int
|
int
|
||||||
mkhtemp_fill_random(char *p, size_t xc)
|
mkhtemp_fill_random(char *p, size_t xc)
|
||||||
{
|
{
|
||||||
static char ch[] =
|
static const char ch[] =
|
||||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
|
||||||
size_t chx = 0;
|
unsigned char scratch[64];
|
||||||
size_t r;
|
|
||||||
|
|
||||||
/* clamp rand to prevent modulo bias
|
size_t off = 0;
|
||||||
*/
|
size_t i;
|
||||||
size_t limit = ((size_t)-1) - (((size_t)-1) % (sizeof(ch) - 1));
|
|
||||||
int saved_errno = errno;
|
/* clamp rand to prevent modulo bias */
|
||||||
|
size_t limit = 256 - (256 % (sizeof(ch) - 1));
|
||||||
|
|
||||||
if (if_err(p == NULL, EFAULT))
|
if (if_err(p == NULL, EFAULT))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
for (chx = 0; chx < xc; chx++) {
|
|
||||||
|
|
||||||
retry_rand:
|
retry_rand:
|
||||||
rset(&r, sizeof(r));
|
rset(scratch, sizeof(scratch));
|
||||||
if (r >= limit)
|
|
||||||
goto retry_rand;
|
|
||||||
|
|
||||||
p[chx] = ch[r % (sizeof(ch) - 1)];
|
for (i = 0; i < sizeof(scratch) && off < xc; i++) {
|
||||||
|
if (scratch[i] < limit)
|
||||||
|
p[off++] = ch[scratch[i] % (sizeof(ch) - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = saved_errno;
|
if (off < xc)
|
||||||
return 0;
|
goto retry_rand;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WARNING: **ONCE** per file.
|
/* WARNING: **ONCE** per file.
|
||||||
|
|||||||
Reference in New Issue
Block a user