-3

So, I have been fiddling around with a code for a ctf competition. However, every time I run the actual console application, it keeps crashing. Could someone please explain to me why. Thank you so much in advance.

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int lowerConvert(char x)
{
    int y;

    if (x == 'a')
        y = 1;
    if (x == 'b')
        y = 2;
    if (x == 'c')
        y = 3;
    if (x == 'd')
        y = 4;
    if (x == 'e')
        y = 5;
    if (x == 'f')
        y = 6;
    if (x == 'g')
        y = 7;
    if (x == 'h')
        y = 8;
    if (x == 'i')
        y = 9;
    if (x == 'j')
        y = 10;
    if (x =='k')
        y = 11;
    if (x == 'l')
        y = 12;
    if (x == 'm')
        y = 13;
    if (x == 'n')
        y = 14;
    if (x == 'o')
        y = 15;
    if (x == 'p')
        y = 16;
    if (x == 'q')
        y = 17;
    if (x == 'r')
        y = 18;
    if (x == 's')
        y = 19;
    if (x == 't')
        y = 20;
    if (x == 'u')
        y = 21;
    if (x == 'v')
        y = 22;
    if (x == 'w')
        y = 23;
    if (x == 'x')
        y = 24;
    if (x == 'y')
        y = 25;
    if (x == 'z')
        y = 26;

    return y;

}
int upperConvert(char x)
{
    int y;

    if (x == 'A')
        y = 27;
    if (x == 'B')
        y = 28;
    if (x == 'C')
        y = 29;
    if (x == 'D')
        y = 30;
    if (x == 'E')
        y = 31;
    if (x == 'F')
        y = 32;
    if (x == 'G')
        y = 33;
    if (x == 'H')
        y = 34;
    if (x == 'I')
        y = 35;
    if (x == 'J')
        y = 36;
    if (x == 'K')
        y = 37;
    if (x == 'L')
        y = 38;
    if (x == 'M')
        y = 39;
    if (x == 'N')
        y = 40;
    if (x == 'O')
        y = 41;
    if (x == 'P')
        y = 42;
    if (x == 'Q')
        y = 43;
    if (x == 'R')
        y = 44;
    if (x == 'S')
        y = 45;
    if (x == 'T')
        y = 46;
    if (x == 'U')
        y = 47;
    if (x == 'V')
        y = 48;
    if (x == 'W')
        y = 49;
    if (x == 'X')
        y = 50;
    if (x == 'Y')
        y = 51;
    if (x == 'Z')
        y = 52;

    return y;
}
char lowerBack(int x)
{
    char y;

    if (x == 1)
        y = 'a';
    else if (x == 2)
        y = 'b';
    else if (x == 3)
        y = 'c';
    else if (x == 4)
        y = 'd';
    else if (x == 5)
        y = 'e';
    else if (x == 6)
        y = 'f';
    else if (x == 7)
        y = 'g';
    else if (x == 8)
        y = 'h';
    else if (x == 9)
        y = 'i';
    else if (x == 10)
        y = 'j';
    else if (x == 11)
        y = 'k';
    else if (x == 12)
        y = 'l';
    else if (x == 13)
        y = 'm';
    else if (x == 14)
        y = 'n';
    else if (x == 15)
        y = 'o';
    else if (x == 16)
        y = 'p';
    else if (x == 17)
        y = 'q';
    else if (x == 18)
        y = 'r';
    else if (x == 19)
        y = 's';
    else if (x == 20)
        y = 't';
    else if (x == 21)
        y = 'u';
    else if (x == 22)
        y = 'v';
    else if (x == 23)
        y = 'w';
    else if (x == 24)
        y = 'x';
    else if (x == 25)
        y = 'y';
    else if (x == 26)
        y = 'z';

        return y;
}
char upperBack(int x)
{
    char y;
    if (x == 27)
        y = 'A';
    if (x == 28)
        y = 'B';
    if (x == 29)
        y = 'C';
    if (x == 30)
        y = 'D';
    if (x == 31)
        y = 'E';
    if (x == 32)
        y = 'F';
    if (x == 33)
        y = 'G';
    if (x == 34)
        y = 'H';
    if (x == 35)
        y = 'I';
    if (x == 36)
        y = 'J';
    if (x == 37)
        y = 'K';
    if (x == 38)
        y = 'L';
    if (x == 39)
        y = 'M';
    if (x == 40)
        y = 'N';
    if (x == 41)
        y = 'O';
    if (x == 42)
        y = 'P';
    if (x == 43)
        y = 'Q';
    if (x == 44)
        y = 'R';
    if (x == 45)
        y = 'S';
    if (x == 46)
        y = 'T';
    if (x == 47)
        y = 'U';
    if (x == 48)
        y = 'V';
    if (x == 49)
        y = 'W';
    if (x == 50)
        y = 'X';
    if (x == 51)
        y = 'Y';
    if (x == 52)
        y = 'Z';


    return y;
}

 void primaryRot13()
{
    cout << "Please enter name of file to be decrypted: ";
    string name;
    getline(cin, name);

    name += ".txt";

    ifstream file;
    ofstream write;
    file.open(name);

    string message;

    file >> message;

    int converted[9999999];
    char reconvert[9999999];

    for (int i = 0; i < message.length();++i)
    {
        if (message[i] == 0 || 1 || 2 || 3 || 4 || 5 || 6 || 7 || 8 || 9)
            message[i] += 53;

        if (message[i] == 'a' || 'b' || 'c' || 'd' || 'e' || 'f' || 'g' || 'h' || 'i' || 'j' || 'k' || 'l' || 'm' || 'n' || 'o' || 'p' || 'q' || 'r' || 's' || 't' || 'u' || 'v' || 'w' || 'x' || 'y' || 'z')
        converted[i] = lowerConvert(message[i]);    
        converted[i] += 13;
        if (converted[i] > 26)
            converted[i] -= 26;

        if (message[i] == 'A' || 'B' || 'C' || 'D' || 'E' || 'F' || 'G' || 'H' || 'I' || 'J' || 'K' || 'L' || 'M' || 'N' || 'O' || 'P' || 'Q' || 'R' || 'S' || 'T' || 'U' || 'V' || 'W' || 'X' || 'Y' || 'Z')
            converted[i] = upperConvert(message[i]);
        converted[i] += 13;
        if (converted[i] > 52)
            converted[i] -= 26;
    }
    for (int i = 0; i < message.length(); ++i)
    {
        if (converted[i] == 52 || 53 || 54 || 55 || 56 || 57 || 58 || 59 || 60 || 61){
            reconvert[i] = converted[i] - 53;
            continue;
        }
        if (converted[i] < 27){
            reconvert[i] = lowerBack(converted[i]);
            continue;
        }
        if (converted[i] < 51){
            reconvert[i] = upperBack(converted[i]);
            continue;
        }
        write.open("decode");
        write << reconvert[i];

    }


}

EDIT AND FINAL SOLUTION Several years later, I am here to repost. What I ended up doing was simply adding the desired amount to the character code, then if it is greater than the upper limit for that set, I subtracted 26 in order to reset. I also ended up using the vector instead, which did solve my issue of crashing. Now I can happily rot13 all day long :) All without the myriad of if statements.

2 Answers2

2

Table Lookup

First, an introduction to table or array look ups.
Given a character array:

static const char letters[] = "abcdefghijklmnopqrstuvwxyz";

The index of 'a' is 0, 'b' is 1, ..., 'z' is 25.
The array can be searched for a letter. The index of the letter can be it's number. In your case, it would be the index + 1.

Example:

static const unsigned int letter_quantity = sizeof(letters) / sizeof(letters[0]);
unsigned int index = 0;
for (index = 0; index < letter_quantity; ++i)
{
  if (letters[i] == x)
  {
    break;
  }
}

At the end of the loop statement, the index variable will be the position of the character in x or the length of the array (if not found).

Modulo Arithmetic

Modulo arithmetic, using the % operator, returns the remainder. It has the behavior of wrapping around. This can be used with the array.

unsigned int new_char_index = index + 13;  // We may have gone past the array.
new_char_index = new_char_index % letter_quantity; // Wrap around.

The New ROT13 Character

The converted character can be found by using the new_char_index as the index into the array.

char rot13 = letters[new_char_index];  

Covering all the characters

The remaining uppercase characters can be added to the array to account for all the letters. Other symbols can be added also.

All this without any if statements.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
1

You're allocating two static arrays of 9999999 elements on the stack.

If an int is 32 bits and a char is 8 bits on your system, then that's 48MB of memory. That's simply too much for the stack.

Try allocating your arrays dynamically instead, i.e. using std::vector:

std::vector<int> converted(9999999);
std::vector<char> reconvert(9999999);
Community
  • 1
  • 1
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
  • We have yet to learn about vectors in class, but I'll do some research. Thank you :) Admittedly, I also had 1 too many nines in there, than what I needed. – David Kluszczynski Mar 20 '15 at 23:52
  • They're actually easier to use than raw C-style arrays, simply because they're harder to misuse. (Especially when you use [`at`](http://www.cplusplus.com/reference/vector/vector/at/) instead of [`[]`](http://www.cplusplus.com/reference/vector/vector/operator[]/) to access the elements.) Btw with one nine less, they're still 5MB, still too much for the stack :P – Emil Laine Mar 21 '15 at 00:05
  • Ah okay, thank you. And yeah, i ended up setting it to 200,000 as i need somewhere around 179,000 give or take. – David Kluszczynski Mar 21 '15 at 15:26