/*
* I R C W 0 R M - N I C K G E N . C
* ---------------------------------
*
* source fragment of ircw0rm C++ source code, from
* original
*
* 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
#include
#include
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 */
}
}