Beispiel #1
0
/** Attempts to push the current piece down */
bool board_push_current_piece_down(Board * b)
{
	// First test if the current piece is already touching something.
	// This can happen if you move sideways and are now touching another piece.
	bool is_on_bottom = !board_can_piece_move_down(b);
	bool result = false;
	if (!is_on_bottom) {
		piece_down(b->current_piece);
		is_on_bottom = !board_can_piece_move_down(b);
		result = true;
	}
	
	if (is_on_bottom){
		// remove the rows
		board_place_piece(b, b->current_piece);
		bool * completed_rows = board_find_completed_rows(b);
		int total_complete_rows = count_true(completed_rows, b->height);
		for (int y=b->height-1; y>=0; y--) {
			if (completed_rows[y]) {
				board_remove_row(b, y);
			}
		}
		free(completed_rows);

		// score the points
		if (total_complete_rows == 1) {
			b->score += 10;
		} else if (total_complete_rows == 2) {
			b->score += 25;
		} else if (total_complete_rows == 3) {
			b->score += 40;
		} else if (total_complete_rows == 4) {
			b->score += 55;
		}
		if (total_complete_rows > 0){
			printf("Score is %i\n", b->score);
		}

		//		board_print(b);
		Piece * next_piece = piece_create_random((b->width / 2), 2);
		if (board_check_valid_placement(b, next_piece)){
			piece_free(b->current_piece);
			b->current_piece = next_piece;						
		} else {
			piece_free(next_piece);
			b->is_done = true;
		}		
	}
	return result;
}
Beispiel #2
0
int main(int argc, char *argv[]) {

    //xor infilename wordlist outfilename
    if (argc != 3) {
//    if (argc != 4) {
        printf("Wrong number of args.\n");
        printf("Xor infile wordlist outfile\n");
        return -1;
    }

    //open the input file to read it
    FILE *cipher_file = fopen(argv[1], "r");
    if (cipher_file == NULL) {
        printf("Couldn't open file; wrong filename?\n");
        return -1;
    }

    //allocate memory for the input strings
    char **input = new char*[NUM_STRINGS];
    unsigned char **bytes = new unsigned char*[NUM_STRINGS];
    bool *useful = new bool[NUM_STRINGS];

    //get the input strings
    for (int i = 0; i < NUM_STRINGS; i++) {
        input[i] = new char[STR_LENGTH];
        //assume there's no error here, because this isn't for anyone else to use
        input[i] = fgets(input[i], STR_LENGTH, cipher_file);
        if (!is_hex_digit(input[i][0])) {
            useful[i] = false;
        } else {
            useful[i] = true;
            bytes[i] = new unsigned char[STR_LENGTH];
        }
    }

    int *num_bytes = new int[NUM_STRINGS];

    //I could do this in the loop above, but for clarity...
    //convert from the characters to their hex values
    //store the numerical value of the hex number in bytes[].
    for (int i = 0; i < NUM_STRINGS; i++) {
        if (useful[i]) {
            for (int j = 0, index = 0; j < STR_LENGTH, index < STR_LENGTH; j++) {
                //input[i] is a char array, so the compiler will automatically
                //multiply index by sizeof(char), I think.
                bytes[i][j] = get_char_from_hex_str(input[i] + index);

                if (input[i][index+2] == '\n') {
                    //j is zero-indexed
                    num_bytes[i] = j + 1;
                    break;
                }

                //two hex digits
                index += 2;
            }
        }
    }


    //get number of useful rows, so we can calculate how many XORs to do
    int num_useful = count_true(useful, NUM_STRINGS);

    //calculate number of XORs - it's
    // \sum_{i=1}^{n-1} i, equal to
    // n*(n-1)/2
    //where n is the number of useful rows
    int num_xors = num_useful * (num_useful - 1) / 2;
    unsigned char ** xors = new unsigned char*[num_xors];
    char **xor_desc = new char*[num_xors];
    int *xor_length = new int[num_xors];

    int xor_it = 0;

    //XOR every byte string against every other byte string
    for (int i = 0; i < NUM_STRINGS; i++) {
        if (useful[i]) {
            for (int j = i + 1; j < NUM_STRINGS; j++) {
                if (useful[j]) {
// ^ is bitwise XOR operator
                    //so we can say which two lines are responsible for an xor
                    xor_desc[xor_it] = new char[DESC_LENGTH];
                    sprintf(xor_desc[xor_it], "%d %d", i, j);
                    xor_length[xor_it] = min(num_bytes[i], num_bytes[j]);
                    xors[xor_it] = new unsigned char[xor_length[xor_it]];
                    for (int k = 0; k < xor_length[xor_it]; k++) {
                        xors[xor_it][k] = bytes[i][k] ^ bytes[j][k];
                    }
                    //make sure we increment this, and LAST in this loop
                    xor_it++;
                }
            }
        }
    }


    //print the XOR'd strings for a sanity check
    for (int i = 0; i < num_xors; i++) {
        printf("%s\n", xor_desc[i]);
        for (int j = 0; j < xor_length[i]; j++) {
            if ((xors[i][j] <= 'z' && xors[i][j] >= 'a') || (xors[i][j] >= 'A' && xors[i][j] <= 'Z') || (xors[i][j] <= '9' && xors[i][j] >= '0')) {
                printf("%c", xors[i][j]);
            } else if (xors[i][j] == '\0'){
                printf("|");
            } else {
                printf(".");
            }
        }
        printf("\n");
    }


    // Now we have a collection of (1) byte arrays and (2) XOR'd byte arrays
    // We're done with the input file, so close it
    fclose(cipher_file);
    // Let's do some analysis!


////////////////////////////////////////////////////////////////////////////////
// Create wordlist
////////////////////////////////////////////////////////////////////////////////




#define MAX_WORDLENGTH 64
#define NUM_WORDS 9900

    FILE *wordlist_file = fopen(argv[2], "r");


    //Idea: XOR the XOR against a wordlist, and if one of the words that appears
    //      appears also in our wordlist, we've found a word in one of the strings
    //      that were XOR'd in that XOR.
    // Words is the same list as words, but with the first char capitalized
    char **words = new char*[NUM_WORDS];
    char **Words = new char*[NUM_WORDS];
    int *word_length = new int[NUM_WORDS];
    for (int i = 0; i < NUM_WORDS; i++) {
        words[i] = new char[MAX_WORDLENGTH];
        Words[i] = new char[MAX_WORDLENGTH];
        fgets(words[i], MAX_WORDLENGTH, cipher_file);

        //remove trailing '\n' from every string
        //and make sure it is null-terminated
        int c = 0;
        do {
            if (words[i][c] == '\n') {
                words[i][c] = '\0';
                word_length[i] = c;
            }
            //YEEAAAHHHH!!!!!
            c++;
        } while (words[i][c] != '\0');
        strncpy(Words[i], words[i], strlen(words[i]));
        Words[i][0] -= (char) 32;
    }


    fclose(wordlist_file);




////////////////////////////////////////////////////////////////////////////////
// Do analysis
////////////////////////////////////////////////////////////////////////////////


#define SMALL_WORD_THRESH 5
#define CHAR_MATCH_THRESH   0.4
 
    //XOR each word from the wordlist against the beginning of each of the XORs
    char *xor_str = new char[MAX_WORDLENGTH];
    char *Xor_Str = new char[MAX_WORDLENGTH];
    bool lowercase;
    for (int xor_it = 0; xor_it < num_xors; xor_it++) {
        for (int strpos_it = 0; strpos_it < xor_length[xor_it]; strpos_it++) {
            for (int word_it = 0; word_it < NUM_WORDS; word_it++) {
                //don't do the xor if the word is too long
                if (word_length[word_it] + strpos_it >= num_bytes[xor_it]) break;

                //xor the word against the first characters of the XOR
                for (int char_it = 0; char_it < word_length[word_it]; char_it++) {
                    xor_str[char_it] = xors[xor_it][char_it+strpos_it] ^ (unsigned char)words[word_it][char_it];
                }
                xor_str[word_length[word_it]] = '\0';
                strncpy(Xor_Str, xor_str, MAX_WORDLENGTH);
                Xor_Str[0] = xors[xor_it][0] ^ (unsigned char)Words[word_it][0];

                //null terminate the first word
                for (int char_it = 0; char_it < MAX_WORDLENGTH; char_it++) {
                    if (xor_str[char_it] == ' ') {
                        xor_str[char_it] = '\0';
                        Xor_Str[char_it] = '\0';
                        break;
                    }
                }

                //compare the result to each word in the list
                for (int word2_it = 0; word2_it < NUM_WORDS; word2_it++) {
                    if (strcmp(words[word2_it], xor_str) == 0 && 
                        //if xor_str is the same as words[word_it], then it was xor'd against 0000... and tells us nothing
                        matching_chars(xor_str, words[word_it]) < (int)CHAR_MATCH_THRESH*word_length[word_it] &&
                        //if the word is sufficiently short, it's probably a coincidence
                        word_length[word2_it] >= SMALL_WORD_THRESH
                    ) {
                        lowercase = true;
                        printf("%s pos %d: word found: %s; xor'd against: %s\n",
                            xor_desc[xor_it], strpos_it, xor_str, words[word_it]
                        );
                    } else if (strcmp(Words[word2_it], Xor_Str) == 0 &&
                        matching_chars(Xor_Str, Words[word_it]) < (int)CHAR_MATCH_THRESH*word_length[word_it] &&
                        word_length[word2_it] >= SMALL_WORD_THRESH
                    ) {
                        lowercase = false;
                        printf("%s pos %d: word found: %s; xor'd against: %s\n",
                            xor_desc[xor_it], strpos_it, Xor_Str, Words[word_it]
                        );
                    }
                }
            }
        }
    }




























    for (int i = 0; i < NUM_WORDS; i++) {
        delete[] words[i];
        delete[] Words[i];
    }
    delete[] words;
    delete[] Words;
    for (int i = 0; i < num_xors; i++) {
        delete[] xors[i];
    }
    delete xors;
    for (int i = 0; i < NUM_STRINGS; i++) {
        delete[] input[i];
        delete[] bytes[i];
    }
    delete[] input;
    delete[] bytes;
    for (int i = 0; i < num_xors; i++) {
        delete[] xor_desc[i];
    }
    delete[] xor_desc;
    delete[] useful;
    return 0;
}