/*-1* SPDX-License-Identifier: 0BSD2*3* Copyright (c) Robert Clausecker <[email protected]>4* Based on a publication by Daniel Lemire.5* Public domain where applicable.6*7* Daniel Lemire, "Fast Random Integer Generation in an Interval",8* Association for Computing Machinery, ACM Trans. Model. Comput. Simul.,9* no. 1, vol. 29, pp. 1--12, New York, NY, USA, January 2019.10*/1112#include <stdint.h>13#include <stdlib.h>1415uint32_t16arc4random_uniform(uint32_t upper_bound)17{18uint64_t product;1920/*21* The paper uses these variable names:22*23* L -- log2(UINT32_MAX+1)24* s -- upper_bound25* x -- arc4random() return value26* m -- product27* l -- (uint32_t)product28* t -- threshold29*/3031if (upper_bound <= 1)32return (0);3334product = upper_bound * (uint64_t)arc4random();3536if ((uint32_t)product < upper_bound) {37uint32_t threshold;3839/* threshold = (2**32 - upper_bound) % upper_bound */40threshold = -upper_bound % upper_bound;41while ((uint32_t)product < threshold)42product = upper_bound * (uint64_t)arc4random();43}4445return (product >> 32);46}474849