int
test() {

    std::string s2 = "yabadabadoo";
    SuffixArray sa2(s2);
    print_ranks(s2, sa2);
    print_suffix_array(s2, sa2);

    vpii_t slcp;
    sa2.lcp_across_sets(4, slcp);
    for (size_t i = 0; i < slcp.size(); ++i) {
        printf("slcp[%d] = (%d, %d)\n", i, slcp[i].INDEX, slcp[i].LENGTH);
    }

    print_pairwise_lcp(s2, sa2);
    // return 0;

    SuffixArray sa1("banana");
    print_ranks("banana", sa1);

    SuffixArray sa3("mississippi");
    print_ranks("mississippi", sa3);

    std::string s4 = "Regular expressions, or just regexes, are at the core of Perl's text processing, and certainly are one of the features that made Perl so popular. All Perl programmers pass through a stage where they try to program everything as regexes, and when that's not challenging enough, everything as a single regex. Perl's regexes have many more features than I can, or want, to present here, so I include those advanced features I find most useful and expect other Perl programmers to know about without referring to perlre, the documentation page for regexes.";
    SuffixArray sa4(s4);
    print_ranks(s4, sa4);
    print_suffix_array(s4, sa4);

    cout<<endl;
    print_pairwise_lcp(s4, sa4);

    return 0;
}
Esempio n. 2
0
 int main(){
 int cases;
 scanf("%d",&cases);
 while(cases--){
 read_input();
 find_ranks();
 print_ranks();
 }
 return 0;
 } 
Esempio n. 3
0
/*
 * "Guided" Random Walk implementation
 */
int solve_diffs_RW(timing_data * data, double
                   diff_weight[KEY_LENGTH][KEY_LENGTH][256], key_data * key)
{

    int i, j, k, u, v;

    unsigned char key_guess[KEY_LENGTH];
    unsigned char new_key_guess[KEY_LENGTH];

    double guess_weights[KEY_LENGTH][256];

    short diffcounts[256];

    int diffs_solved = 0;

    for(i = 1; i < KEY_LENGTH; i++) {
        for(j = 0; j < 256; j++) {
            guess_weights[i][j] = 0;

            guess_weights[i][j] += diff_weight[0][i][j];

            for(u = 1; u < i; ++u) {
                double low_weight = 10000;
                for(v = 0; v < 256; v++)
                    if(diff_weight[0][u][v] + diff_weight[u][i][v ^ j] < low_weight)
                        low_weight = diff_weight[0][u][v] + diff_weight[u][i][v ^ j];

                guess_weights[i][j] += low_weight;
            }


            for(u = i + 1; u < KEY_LENGTH; ++u) {
                double low_weight = 10000;
                for(v = 0; v < 256; v++)
                    if(diff_weight[0][u][v] + diff_weight[i][u][v ^ j] < low_weight)
                        low_weight = diff_weight[0][u][v] + diff_weight[i][u][v ^ j];

                guess_weights[i][j] += low_weight;
            }
        }
    }

    printf("\nRW:");
    print_ranks(guess_weights, key);

    //Make initial best guess
    for(i = 1; i < KEY_LENGTH; ++i)
    {
        double min_seen = guess_weights[i][0];
        for(j = 0; j < 256; ++j)
            if(guess_weights[i][j] <= min_seen)
            {
                min_seen =guess_weights[i][j];
                key_guess[i] = j;
            }
    }

    if(guess_key(key_guess, data, key))
        return 1;


    int round = 1;
    double guess_weight;

    for(round = 0; round < RANDOM_WALK_LIMIT; round++) {

        for(i =1; i < KEY_LENGTH; i++) {
            for(j = 0; j < 256; j++) {
                guess_weight = diff_weight[0][i][j];

                for(k = 1; k < i; k++)
                    guess_weight +=diff_weight[k][i][j ^ key_guess[k]];

                for(k = i +1; k < KEY_LENGTH; k++)
                    guess_weight +=diff_weight[i][k][j ^ key_guess[k]];

                guess_weights[i][j] = guess_weight;
            }

        }

        int best_byte = 1;
        double best_gain =0;
        //Make single best guess
        for(i = 1; i < KEY_LENGTH; ++i)
        {
            double min_seen = guess_weights[i][0];
            for(j = 0; j < 256; ++j)
                if(guess_weights[i][j] <= min_seen)
                {
                    min_seen =guess_weights[i][j];
                }

            if(guess_weights[i][key_guess[i]] - min_seen > best_gain)
            {
                best_gain = guess_weights[i][key_guess[i]] - min_seen;
                best_byte = i;

            }
        }

        double min_seen = guess_weights[best_byte][0];
        for(j = 0; j < 256; ++j)
            if(guess_weights[best_byte][j] <= min_seen)
            {
                min_seen =guess_weights[best_byte][j];
                key_guess[best_byte] = j;
            }

        /*  printf("\nUpdating byte #%d", best_byte); */

        /*     printf("\nRound #%d", round); */
        /*      print_ranks(guess_weights, key); */

        if(guess_key(key_guess, data, key))
            return 1;

    }


    return 0;
}
Esempio n. 4
0
/*
 * Belief propagation implementation
 */
int solve_diffs_BP(timing_data * data, double
                   diff_prob[KEY_LENGTH][KEY_LENGTH][256], key_data * key)
{

    int i, j, k, u, v;

    unsigned char key_guess[KEY_LENGTH];
    unsigned char new_key_guess[KEY_LENGTH];

    double guess_prob[KEY_LENGTH][256];
    double next_guess_prob[KEY_LENGTH][256];

    short diffcounts[256];

    int diffs_solved = 0;

    for(i = 1; i < KEY_LENGTH; i++) {
        for(j = 0; j < 256; j++) {
            guess_prob[i][j] = 0;

            guess_prob[i][j] += diff_prob[0][i][j];

            for(u = 1; u < i; ++u) {
                double high_prob = 0;
                for(v = 0; v < 256; v++)
                    if(diff_prob[0][u][v] + diff_prob[u][i][v ^ j] > high_prob)
                        high_prob = diff_prob[0][u][v] + diff_prob[u][i][v ^ j];

                guess_prob[i][j] += high_prob;
            }


            for(u = i + 1; u < KEY_LENGTH; ++u) {
                double high_prob = 0;
                for(v = 0; v < 256; v++)
                    if(diff_prob[0][u][v] + diff_prob[i][u][v ^ j] > high_prob)
                        high_prob = diff_prob[0][u][v] + diff_prob[i][u][v ^ j];

                guess_prob[i][j] += high_prob;
            }
        }
    }

    normalize(guess_prob);

    printf("\nBP:");
    print_ranks(guess_prob, key);

    //Make initial best guess
    for(i = 1; i < KEY_LENGTH; ++i)
    {
        double max_seen = 0;
        for(j = 0; j < 256; ++j)
            if(guess_prob[i][j] >= max_seen)
            {
                max_seen =guess_prob[i][j];
                key_guess[i] = j;
            }
    }

    if(guess_key(key_guess, data, key))
        return 1;


    int round = 1;
    /*   double guess_weight; */

    for(round = 0; round < RANDOM_WALK_LIMIT; round++) {
        for(i = 1; i < KEY_LENGTH; i++)
            for(j = 0; j < 256; j++) {
                next_guess_prob[i][j] = 0;


                for(u = 1; u < i; ++u) {
                    double high_prob = 0;

                    for(v = 0; v < 256; v++)
                        if(guess_prob[u][v] * diff_prob[u][i][v ^ j] > high_prob)
                            high_prob = guess_prob[u][v] * diff_prob[u][i][v ^ j];

                    next_guess_prob[i][j] += high_prob;
                }

                for(u = i + 1; u < KEY_LENGTH; ++u) {
                    double high_prob = 0;

                    for(v = 0; v < 256; v++)
                        if(guess_prob[u][v] * diff_prob[i][u][v ^ j] > high_prob)
                            high_prob = guess_prob[u][v] * diff_prob[i][u][v ^ j];

                    next_guess_prob[i][j] += high_prob;
                }

            }

        for(i = 1; i < KEY_LENGTH; i++)
            for(j = 0; j < 256; j++)
                guess_prob[i][j] = next_guess_prob[i][j];

        normalize(guess_prob);


        /*     printf("\nRound #%d", round); */
        /*      print_ranks(guess_prob, key); */

        for(i = 1; i < KEY_LENGTH; ++i)
        {
            double max_seen = 0;
            for(j = 0; j < 256; ++j)
                if(guess_prob[i][j] >= max_seen)
                {
                    max_seen =guess_prob[i][j];
                    key_guess[i] = j;
                }
        }

        if(guess_key(key_guess, data, key))
            return 1;

    }

    return 0;
}