/* * I R C W 0 R M - N I C K G E N . C * --------------------------------- * * source fragment of ircw0rm C++ source code, from * <a href="http://pastebin.ca/154650">original</a> * * provided by drnez on #hackphreak * updates, comments and analysis by grkvlt * updated: 01h22, friday 15 september 2006 *//* * the algorithm produces a random string of both lower- and * upper-case letters and optionally numbers. the distribution * of letters is as follows (in 1/15ths): * * [aAzZ] 0 0.0% * [b-n] 6 40.0% * [o-y] 4 26.7% * [B-G] 2 13.3% * [H-Y] 3 20.0% * * also, there is a skew in the distribution due to the fact * that MAX_INT is not divisible by 90, so the first MAX_INT % 90 * characters are more likely to appear with a probability * of 1 / (MAX_INT / 90) or 0.13% approximately, over the rest * of the alphabet. this is pretty insignificant compared to the * distribution percentages above. * * additionally, if at any time 60 is produced as a random number, * the string will be truncated (if it is zero-filled) or will retain * the initial value for that character position. this occurs 1 / 90 * or 1.1% of the time, and is not accounted for in the table above. * * whether the distributions are useful is another matter. it * is easy to show that a nick does *not* conform to this pattern, * just loom for '[aAzZ]' anywhere. to prove that a string has * the same distribution with just eight samples (characters) * will be very error-prone, and requires more statistics-fu than * i can remember at present, although it is an interesting * problem...!. * * note that the original fragment was C++ and this function and * associated test harness are in C. this should not affect the operation * of the algorithm or the output, but see comments below regarding * the seeding of the prng. *//* * sample output below. note line four, where output is truncated after six * characters, since randn == 60 and the initial buffer is zero-filled, so * any skipped characters are interpreted as '\0' or end of string. * * "TXJcwNvh" * "NThRpOlJ" * "kYIbtRSn" * "hRrSPn" * "sgqcBTGq" * "ijmLTTgs" * "dkmtiOks" * *//* * standard include files and definition of BOOL type for C */#include <stdio.h>#include <stdlib.h>#include <time.h>typedef int BOOL;#define TRUE (1 == 1)#define FALSE (1 == 0)/* * generate a random string of characters */void RandomString(char *dst, int len, BOOL Gen_Numbers) { int i = 0, randn = 0; do { /* gen random number between 0 and 90 */ randn = (rand() % 90); if (randn < 30 && i!=0 && Gen_Numbers == TRUE) { dst[i] = (48 + (rand() % 9)); /* gen number */ } else if (randn < 60) { dst[i] = (98 + (rand() % 24)); /* gen lower case letter */ } else if (randn > 60) { dst[i] = (66 + (rand() % 24)); /* gen upper case letter */ } i++; len--; } while (len != 0); dst[i] = (char)0; /* null terminate */}/* * exercise the RandomString function in an infinite loop, generating * a new random, 8-character letter-only, string each time round. * * no error checking for calloc() or time() library calls. * * compile and run as: * gcc ircw0rm-nickgen.c -o ircw0rm-nickgen * ./ircw0rm-nickgen */int main(int argc, char **argv) { char *buf; /* pointer to string buffer */ /* * init random number generator with system time (in seconds). in * the original code, this was inside RandomString and used GetTickCount * which has millisecond resolution. since we call the function many * times a second, using time() to re-seed the prng each iteration would * just generate lots of duplicates until the next second, so simply * seed once per execution. */ srand((int)time(NULL)); /* infinite loop */ while (TRUE) { buf = (char *)calloc(9, sizeof(char)); /* alloc 9 chars, zeroed */ RandomString(buf, 8, FALSE); /* eight characters, no numbers */ printf("\t\"%s\"\n", buf); /* output generated string in quotes */ free(buf); /* free the buffer */ }}