#include #include #include #include "rnd.h" /* https://www.math.cornell.edu/~mec/2003-2004/cryptography/subs/frequencies.html */ #define ALPHABET_SIZE 26 #define RND_MAXINT 10000 struct letter_frequency { int p; /* pegged to 10000 rather than 1 */ char c; } letter_frequencies[] = { { 7, 'Z'}, { 10, 'J'}, { 11, 'Q'}, { 17, 'X'}, { 69, 'K'}, { 111, 'V'}, { 149, 'B'}, { 182, 'P'}, { 203, 'G'}, { 209, 'W'}, { 211, 'Y'}, { 230, 'F'}, { 261, 'M'}, { 271, 'C'}, { 288, 'U'}, { 398, 'L'}, { 432, 'D'}, { 592, 'H'}, { 602, 'R'}, { 628, 'S'}, { 695, 'N'}, { 731, 'I'}, { 768, 'O'}, { 812, 'A'}, { 910, 'T'}, { 1202, 'E'},}; /* from http://stackoverflow.com/questions/822323/how-to-generate-a-random-number-in-c */ int random_number(int min_num, int max_num) { static int initialised = 0; int result = 0; int low_num = 0; int hi_num = 0; if (min_num < max_num) { low_num = min_num; hi_num = max_num + 1; // this is done to include max_num in output. } else { low_num = max_num + 1; // this is done to include max_num in output. hi_num = min_num; } if (!initialised) { srand(time(NULL)); initialised = 1; } result = (rand() % (hi_num - low_num)) + low_num; return result; } char get_random_letter() { int rnd = random_number(0, RND_MAXINT); for (int i = 0; i < ALPHABET_SIZE; i++) { if (rnd < letter_frequencies[i].p) { return letter_frequencies[i].c; } rnd -= letter_frequencies[i].p; } return '\0'; } #ifdef DEBUG_RND_MAIN #include int main() { int n = 32; while (--n > 0) { printf("%c", get_random_letter()); } return 0; } #endif