#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>

/*************************************************************************/

/* fizzer types and funcs and etc */
typedef unsigned int RNGState[0x160];
static char nick[128];
void gen_nick(void);
unsigned int get_yyyymmdd(void);
RNGState *fizzer_initrand(RNGState *state, unsigned int seed);
void fizzer_srand(RNGState *state, unsigned int seed);
unsigned int fizzer_random(RNGState *state);
int randrange(RNGState *state, int low, int high);
unsigned int srandrange(unsigned int low, unsigned int high,
                        unsigned int seed, RNGState *state);

/*************************************************************************/

time_t my_time = 0;

int main(int ac, char **av)
{
    if (ac > 1 && strcmp(av[1],"-h") == 0) {
	fprintf(stderr, "Usage: %s [timestamp]\nTimestamp defaults to now if"
		" not explicitly given.\n", av[0]);
	return 1;
    }
    if (ac > 1)
	my_time = atoi(av[1]);
    gen_nick();
    printf("%s", nick);
    return 0;
}

/*************************************************************************/
/* decompiled fizzer extracts below, watch your step! */

void gen_nick(void)  /* at 0x413C92 */
{
    RNGState state;	/* EBP-0x580 */
    int pos;
    fizzer_initrand(&state, get_yyyymmdd());
    pos = 0;
    while (pos < 0x500) {
	(void) fizzer_random(&state);
	(void) fizzer_random(&state);
	pos += 0x80;
    }
    bzero(nick, sizeof(nick));
    nick[0] = srandrange('A', 'Z', 0, &state);
    nick[1] = srandrange('A', 'Z', 0, &state);
    nick[2] = srandrange('A', 'Z', 0, &state);
}
unsigned int get_yyyymmdd(void)
{
#if 0
    SYSTEMTIME systime;	/* EBP-0x10 */
    bzero(&systime, sizeof(systime));
    GetSystemTime(&systime);
    return (systime.wYear*100 + systime.wMonth) * 100 + systime.wDay;
#else
    unsigned int x = 0;
    time_t t = time(NULL);
    struct tm *tm = gmtime(&t);
            
    if(my_time)
      return my_time;

    x += (tm->tm_year+1900) * 10000;
    x += (tm->tm_mon+1) * 100;
    x += tm->tm_mday;

    return x;
#endif
}
RNGState *fizzer_initrand(RNGState *state, unsigned int seed)
{
    fizzer_srand(state, seed);
    return state;
}
void fizzer_srand(RNGState *state, unsigned int seed)
{
    int i;
    (*state)[0x15F] = 0;
    while ((*state)[0x15F] < 0x15F) {
	seed *= 0x1C8E815;
	seed--;
	(*state)[(*state)[0x15F]++] = seed;
    }
    for (i = 1000; i != 0; i--)
	(void) fizzer_random(state);
}
unsigned int fizzer_random(RNGState *state)
{
    if ((*state)[0x15F] >= 0x15F) {
	int j = 0xAF;
	unsigned int *ptr = (unsigned int *)state;
	int i = 0x15E;
	while (i != 0) {
	    unsigned int b = ptr[0];  /* b because stored in ebx */
	    unsigned int a = ptr[1];  /* likewise */
	    a ^= b;
	    a &= 0x7FFFF;
	    a ^= b;
	    b ^= a;
	    b &= 1;
	    b = -((signed) b);
	    b &= 0xE4BD75F5;  /* 0xE4BD75F5 or zero */
	    b ^= (*state)[j];
	    a >>= 1;
	    b ^= a;
	    *ptr = b;
	    j++;
	    if (j >= 0x15F)
		j = 0;
	    i--;
	    ptr++;
	}  /* while (i != 0) */
	{
	    unsigned int d = (*state)[0x15E];
	    unsigned int a = d;
	    a ^= (*state)[0];
	    a &= 0x7FFFF;
	    a ^= d;
	    d = -(a & 1) & 0xE4BD75F5;
	    d ^= (*state)[0xAE];
	    a >>= 1;
	    d ^= a;
	    (*state)[0x15F] = 0;
	    (*state)[0x15E] = d;
	}
    }  /* if ((*state)[0x15F] >= 0x15F) */
    return (*state)[(*state)[0x15F]++];
}

int randrange(RNGState *state, int low, int high)
{
    double tmp1, tmp2, tmp3;
    int val;
    tmp1 = fizzer_random(state);
    
/*    printf("%.0f\n", tmp1); */

    tmp1 /= (double)0xFFFFFFFF;
    tmp2 = high;
    tmp3 = low;
    if (tmp3 < 0)
	tmp3 = 0;
    if (tmp2 > 0xFFFFFFFF)
	tmp2 = 0xFFFFFFFF;
    tmp2 -= tmp3;
    tmp2 += 1;
    tmp2 *= tmp1;
    val = (int)floor(tmp2+0.5) + low;
    if (val > high)
	val = high;
    if (val < low)
	val = low;
    return val;
}

unsigned int srandrange(unsigned int low, unsigned int high,
                        unsigned int seed, RNGState *state)
{
    return randrange(state, low, high);
}

