* @brief Generates a random number bounded by the given value. * @param bound Upper bound (exclusive) * @return Random number in range [0, bound) */
| 848 | * @return Random number in range [0, bound) |
| 849 | */ |
| 850 | auto Pass::boundedRandom(quint32 bound) -> quint32 { |
| 851 | if (bound < 2) { |
| 852 | return 0; |
| 853 | } |
| 854 | |
| 855 | quint32 randval; |
| 856 | // Rejection-sampling threshold to avoid modulo bias. |
| 857 | // This follows the well-known "arc4random_uniform"-style approach: |
| 858 | // reject values in the low range [0, min), where |
| 859 | // min = 2^32 % bound |
| 860 | // so that the remaining range size is an exact multiple of `bound`. |
| 861 | // |
| 862 | // In quint32 arithmetic, (1 + ~bound) wraps to (2^32 - bound), therefore |
| 863 | // (1 + ~bound) % bound == 2^32 % bound. |
| 864 | const quint32 rejectionThreshold = (1 + ~bound) % bound; |
| 865 | |
| 866 | do { |
| 867 | randval = QRandomGenerator::system()->generate(); |
| 868 | } while (randval < rejectionThreshold); |
| 869 | |
| 870 | return randval % bound; |
| 871 | } |
| 872 | |
| 873 | /** |
| 874 | * @brief Generates a random password from the given charset. |
nothing calls this directly
no outgoing calls
no test coverage detected