/* * write lines from stdin to stdout in random order * * updated 2012-12-24 to seed rand using FNV hash of command-line argument * * R. Perry, Oct. 2002 */ #include #include #include #include unsigned int hash( unsigned char buf[], int n) { unsigned int h = 2166136261; for( int i = 0; i < n; ++i) { h = 16777619 * h ^ buf[i]; } return h; } char *progname; char **stack = NULL; size_t size = 0; size_t count = 0; void *erealloc( void *q, size_t bytes) { void *p = realloc( q, bytes); if( p == NULL) { fprintf( stderr, "%s: realloc() failed.\n", progname); exit(1); } return p; } void push( char *line) { if( count >= size) { size = 1.5*size + 100; stack = erealloc( stack, size*sizeof(char*)); } stack[count] = erealloc( NULL, strlen(line)+1); strcpy( stack[count], line); ++count; } void print( void) { size_t i; for( i = 0; i < count; ++i) fputs( stack[i], stdout); } void randomize( void) { char *t; size_t i, j; if( count <= 1) return; for( i = count - 1; i > 0; --i) { j = (rand()/(RAND_MAX+1.0))*(i+1); /* 0 .. i */ if( i != j) /* swap */ { t = stack[i]; stack[i] = stack[j]; stack[j] = t; } } } int main( int argc, char *argv[]) { unsigned seed; char line[BUFSIZ]; progname = argv[0]; if( argc > 1) seed = hash( (unsigned char *) argv[1], strlen(argv[1])); else seed = time(0); #if 0 printf( "%u\n", seed); #endif srand( seed); while( fgets( line, BUFSIZ, stdin)) { push( line); } randomize(); print(); return 0; }