예제 #1
0
tuple_t extEuclid(unsigned int a, unsigned int b) {
    if(a < b) { // a must be the greater one
        unsigned int t = a;
        a = b;
        b = t;
    }

    if(b == 0) return (tuple_t){1, 0, a};

    tuple_t t = extEuclid(b, a % b);
    return (tuple_t){t.b, t.a - (a/b) * t.b, t.c};
}
예제 #2
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);
}
예제 #3
0
 int modInv(int n, int m) {
     int x, y, gcd;
     extEuclid(n, m, x, y, gcd);
     if (gcd == 1) return x % m;
     return 0;
 }