All pastes #171121 Raw Edit

ircw0rm nickgen analysis

public c v1 · immutable
·published 2006-09-15 01:39 UTC
rendered paste body
/* *      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 */    }}