#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
// Define explicit bounds for readability and maintainability
#define MIN_8_DIGIT 10000000L
#define MAX_8_DIGIT 99999999L
/**
* Initializes the random number generator seed.
* Call this ONCE at the start of your application (e.g., in main).
*/
void init_random(void) {
// Seed using the current time in seconds
srand((unsigned int)time(NULL));
}
/**
* Generates a random 32-bit unsigned integer spanning a wider range
* than standard rand() on platforms where RAND_MAX is 32767 (15-bit).
*
* @return A 31-bit pseudo-random integer.
*/
static int32_t generate_large_rand(void) {
#if RAND_MAX >= 2147483647
// Platform has a 31-bit or larger RAND_MAX (e.g., Linux glibc)
return rand();
#else
// Combine two 15-bit rand() calls to construct a larger value (MSVC/Windows)
return ((int32_t)(rand() & 0x7FFF) << 15) | (int32_t)(rand() & 0x7FFF);
#endif
}
/**
* Generates an 8-digit random integer between 10,000,000 and 99,999,999 (inclusive).
* Uses modulo bias elimination for precise uniform distribution.
*
* @return An 8-digit random integer.
*/
long generate_8_digit_number(void) {
long range = MAX_8_DIGIT - MIN_8_DIGIT + 1L; // 90,000,000 values
// Calculate the threshold to remove modulo bias for strict uniform distribution
int32_t max_usable = (INT32_MAX / range) * range;
int32_t raw_rand;
// Reject samples that fall into the incomplete top bucket
do {
raw_rand = generate_large_rand();
} while (raw_rand >= max_usable);
return MIN_8_DIGIT + (raw_rand % range);
}
/**
* Formats a random 8-digit string allowing leading zeros ( range: "00000000" to "99999999" ).
* Useful for OTPs, PINs, or fixed-width tracking identifiers.
*
* @param buffer Output char array of size at least 9 (8 digits + null terminator).
* @param size Size of the buffer array.
*/
void generate_8_digit_string(char *buffer, size_t size) {
if (buffer == NULL || size < 9) {
return; // Guard clause against buffer overflow
}
long raw_value = generate_large_rand() % 100000000L;
snprintf(buffer, size, "%08ld", raw_value);
}
int main(void) {
// 1. Seed the RNG exactly once
init_random();
// 2. Generate an 8-digit mathematical integer
long number = generate_8_digit_number();
printf("Generated 8-digit integer: %ld\n", number);
// 3. Generate an 8-digit string code (preserves leading zeros)
char code_str[9];
generate_8_digit_string(code_str, sizeof(code_str));
printf("Generated 8-digit code string: %s\n", code_str);
return 0;
}
/*
run:
Generated 8-digit integer: 91801077
Generated 8-digit code string: 09220095
*/