Exemplo n.º 1
0
/* Generate strings len long and print n strings that hash to 0
 * Referenced: http://codereview.stackexchange.com/q/38474 */
static void generate(int size, int len, char *string, int i, int *n) {
    // Constrain characters between A and z
    // to allow all characters: (char c = 1; c > 0 && *n > 0; c++)
    for (unsigned char c = MINCHAR; c <= MAXCHAR && *n > 0; c++) {
        string[i] = c;

        if (i == len - 1) {
            if (!universal_hash((unsigned char*) string, size)) {
                printf("%s\n", string);
                if (!--*n) break;
            }
        } else generate(size, len, string, i + 1, n);
    }
}
Exemplo n.º 2
0
/* Determine the value that combined with string hashes to 0 */
static char hash_zero(int *coeffs, char *string, int size, int c) {
    gcd euclid = extended_euclid(size, coeffs[c]);

    // euclid.y + size to ensure it's positive
    euclid.y = (euclid.y + size) % size;

    // Get the hash of string excluding the char at c
    int hash = universal_hash((unsigned char*)string, size);
    hash -= coeffs[c] * (unsigned char) string[c] % size;

    // size is prime so euclid.y * coeffs % size = 1
    // So hash + (size - hash) * 1 = size % size = 0
    return (size - hash) * euclid.y % size;
}
/* Print n strings that are hashed to 0 by universal_hash seeded with seed */
void collide_dumb(unsigned int size, unsigned int seed, int n) {
	
	char* zeroHashStrings[n];
	
	int zeroHashCounter = 0 ;
	
	//While we don't have enough random numbers, keep trying strings
	while(zeroHashCounter < n)
	{
		char* string = randstring();
		
		if(universal_hash((unsigned char*)string, size)==0)
		{
			zeroHashStrings[zeroHashCounter]= string;
			zeroHashCounter++;
		}
		
		
	}

	//The number of r values generated is always the maximum string length
	fprintf(stdout, "%d\n", MAXSTRLEN);
	
	//Reinitialize the random number generator to get the values we want
	srand(seed);
	
	
	//Print the r values
	int i;
	for(i = 0 ; i < MAXSTRLEN; i++)
	{
		fprintf( stdout, "%d\n" ,rand()%size);
	}

   
	for(i = 0 ; i < n; i++)
	{
		fprintf( stdout, "%s\n" ,zeroHashStrings[i]);
	}


}
Exemplo n.º 4
0
/* Print n strings that are hashed to 0 by universal_hash seeded with seed
 * although character can be anything <255, only 'pretty' characters are chosen
 * for the 'prettiness' of the output */
void collide_clever(unsigned int size, unsigned int seed, int n) {
    static bool   first = true;
    int           randSize, sum, gen, i, x, toChange, *randArr = NULL;
    unsigned char y, *line = malloc(sizeof(*line) * MAX_LEN);
    // index randsize will be '\0'. Therefore, randsize < MAXLEN.

#if I_DUNNO_STATS
    unsigned char **used   = malloc(sizeof(*used) * n);
    int           useCount = 0;
#endif

    if(size > 255) {
        fprintf(stderr, "Size is too big. Outside assignment scope!\n");
        fprintf(stderr, "I had spent ages addressing that but after nerf,\n");
        fprintf(stderr, "and reached the state where generated string hash to one index for any size.\n");
        fprintf(stderr, "But no point working further on and submitting risky long code.\n");
        fprintf(stderr, "Anyway, terminating in sass :P\n");
        exit(EXIT_FAILURE);
    }

    // initialize universal hash's random array
    if(first == true) { // some say there are still first == true for most CompSc students
        first = false;
        srand(seed);
        universal_hash(line, size);
    }

    // find out which index to work on
    randArr = getRandArray(seed, size);
    i = 0;
    while(randArr[i] == 0)
        i++;
    toChange = i;

#if GET_TIME
    clock_t start = clock();
    fprintf(stderr, "N: %d\nSIZE: %d\n", n, size);
#endif

    // initialize my random array
    while(n > 0) {
        sum = 0;

        randSize       = rand() % (MAX_LEN - INIT_SIZE - 1) + INIT_SIZE;
        line[randSize] = '\0';

        for(i = 0; i < randSize; i++) {
            if(i != toChange) {
                line[i] = rand() % (MAX_ASCII - START_ASCII - 1) + START_ASCII;
                sum += (line[i] * randArr[i]);
            }
        }

        // explanation of how and why this works and the algorithm is in the report, question 7.
        gen       = size - (sum % size);
        tuple_t t = extEuclid(size, randArr[toChange]);

        x = t.b * gen / t.c;

        if(x < 0)
            y = size - ((-x) % size);
        else
            y = x % size;

        if(y < START_ASCII && size + y < MAX_ASCII) {
            y += size * (1 + (START_ASCII - y) / size);
            // minimum multiple of size to add to make y fall within given range
        } else if(y == '\n' || y == 127 || y <= 32) { // 127 = DEL ASCII
            // if the string genrated has newline character, solution is not valid since
            // strings are loaded with fgets().
            // this happens is about 0.3% of the time.
            // Forum post requirement: avoid characters from 0-32.
            continue;
            // had attempted to add minimum multiple of size,
            // faster to generate new rather than resolve
        }

        line[toChange] = y;

#if I_DUNNO_STATS
        for(i = 0; i < useCount; i++) {
            // make sure it is not duplicate
            if(strcmp((char*) used[i], (char*) line) == 0)
                break;
        }

        used[useCount] = malloc(sizeof(unsigned char) * (strlen((char*)line) + 1));
        strcpy((char*)used[useCount], (char*)line);
        // fprintf(stderr, "USED %d: %s\n", useCount, used[useCount]);
        useCount++;
#endif

        fprintf(stdout, "%s\n", line);
        n--;
    }

#if GET_TIME
    clock_t end = clock();
    fprintf(stderr, "TIME TAKEN: %.5f s\n", ((double) end - start) / CLOCKS_PER_SEC);
#endif

#if I_DUNNO_STATS
    for(i = 0; i < useCount; i++) {
        free(used[i]);
    }
    free(used);
#endif
    free(randArr);
    free(line);
}
Exemplo n.º 5
0
/* Print n strings that are hashed to 0 by universal_hash seeded with seed
 * although character can be anything <255, only 'pretty' characters are chosen
 * for the 'prettiness' of the output */
void collide_dumb(unsigned int size, unsigned int seed, int n) {
    static bool   first    = true;
    int           *randArr = getRandArray(seed, size);
    unsigned int  randSize, i, try;
    unsigned char *line    = malloc(sizeof(*line) * MAX_LEN);

#if I_DUNNO_STATS
    unsigned char **used   = malloc(sizeof(*used) * n);
    unsigned int useCount  = 0;
    // index randsize will be '\0'. Therefore, randsize < MAXLEN.
#endif

    if(first == true) { // if virgin, initialize universal hash
        first = false;
        srand(seed);
        universal_hash(line, size);
    }

#if GET_TIME
    clock_t start = clock();
    fprintf(stderr, "N: %d\nSIZE: %d\n", n, size);
#endif

    while(n > 0) {
        try = 0;
        randSize = rand() % (MAX_LEN - INIT_SIZE - 1) + INIT_SIZE;
        // -1 for \0 slot

        while(try <= MAX_TRY) {
            for(i = 0; i < randSize; i++)
                line[i] = rand() % (MAX_ASCII - START_ASCII - 1) + START_ASCII;


            line[randSize] = '\0';

            if(universal_hash(line, size) == 0) {
#if I_DUNNO_STATS
                for(i = 0; i < useCount; i++) {
                    // make sure it is not duplicate
                    if(strcmp((char*) used[i], (char*) line) == 0)
                        break;
                }

                used[useCount] = malloc(sizeof(unsigned char) * (strlen((char*)line) + 1));
                strcpy((char*)used[useCount], (char*)line);
                // fprintf(stderr, "USED %d: %s\n", useCount, used[useCount]);
                useCount++;
#endif

                fprintf(stdout, "%s\n", line);
                n--;
                break; // now generate new random size!
            }
        }
    }

#if GET_TIME
    clock_t end = clock();
    fprintf(stderr, "TIME TAKEN: %.5f s\n", ((double) end - start) / CLOCKS_PER_SEC);
#endif

#if I_DUNNO_STATS
    for(i = 0; i < useCount; i++) {
        free(used[i]);
    }
    free(used);
#endif
    free(randArr);
    free(line);
}