Member Avatar for TheFearful

Hello everyone, can anyone explain to me what is wrong with my project? I coded the program using my linux system using Vim and the g++ compiler. I then copied that text over to Visual Studio since I am assuming my professor is going to compile and run it through Visual Studio and will not grade the project if it does not compile or run. In Visual Studio, it compiles fine(I had to create integer and assign them to the length of the string since it seems to be giving me issues about that even though it doesn't in my linux system) but keeps having a runtime error and I don't know why.

In my Linux system, it compiles and runs effortlessly. Am I missing something in Visual Studio?

here's my code. Any help regarding why it's giving my issues in Visual Studio would be very much appreciated (:

/*************************************
*Author:
*Class: CPSC 370 Computer Cryptology
*Due Date: 9-13-2015
*Assignment 1: Shift Cipher
*************************************/

#include <iostream>
#include <string.h>
#include <string>
using namespace std;


//functions
string bruteforce(string b);
char encrypt(char e);
char ddecrypt(char d);

//part 2 functions
char affine(char f);
char affine2(char b, int beta);


//global declarations
string cipher           = "KDDKMU"; //the string we are trying to decrypt
string LETTERS          = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //The letters in the alphabet being used
string decrypt          = ""; //empty string to get all of our shift cipher keys

//part 2 global declarations
string cipher2      = "YCVEJQWVHQTDTWVWU"; //the string we are trying to decrypt
string ciphertext2  = "EDSGICKXHUKLZVEQZVKXWKZUKCVUH"; //we need to decrypt this us the plaintext affine "if"
string ciphertext3  = "TCABTIQMFHEQQMRMVMTMAQ"; //we need to decrypt this using the affine function 3x + b for some b

string plaintext        = "cleopatra"; //plaintext to encrypt
string ciphertext       = "MZDVEZC"; //ciphertext to decrypt

int length1 = cipher.length();
int length2 = LETTERS.length();
int length3 = decrypt.length();
int length4 = cipher2.length();
int length5 = ciphertext2.length();
int length6 = ciphertext3.length();
int length7 = plaintext.length();
int length8 = ciphertext.length();

int main()
{

    decrypt = bruteforce(cipher); //calls the function to bruteforce the chipertext

    cout << endl << "Time to encrypt cleopatra." << endl;
    string output = "";//empty string to encrypt our plaintext
    for(int i = 0; i < length7; i++)
    {
        output += encrypt(plaintext[i]);

    }
    //prints the result of the encrypted plaintext
    cout << output << endl;

    cout << "Time to decrypt MZDVEZC" << endl;
    output = ""; //clears the output from encrypting cleopatra

    //The loop will iterate for the total length of the message
    for(int i = 0; i < length8; i++)
    {
        /*
        *Adds a value to the string for each iteration of
        *the loop by calling the ddecrypt function that will
        *use the affine equation given to figure out what letter
        *was being use to encrypt the message so that the message
        *will be decrypted completely once the loop is done
        */
        output += ddecrypt(ciphertext[i]);
    }
        //outputs the result of the decrypted message
        cout << output;

    //part 2
    cout << endl << endl << "Time for some extra credit!" << endl;  
    decrypt = bruteforce(cipher2); //calls the function to bruteforce the ciphertext
    cout << endl << "Time to decrypt EDSGICKXHUKLZVEQZVKXWKZUKCVUH" << endl;
    output = ""; //clears the output from decrypting MZDVEZV

    for(int i = 0; i < length5; i++)
    {
        //Same as the loop directly above this one
        //but with a different affine equation
        output += affine(ciphertext2[i]);
    }
    cout << output << endl << endl; //outputs the result

    output = ""; //clears the output from the last decryption
    for(int i = 0; i < length2; i++)
    {
        output = ""; //clears the output at the start of each iteration
        for(int j = 0; j < length6; j++)
        {
            output += affine2(ciphertext3[j], i);
            cout << output[j]; //outputs the decrypted key for each value of beta we give it from the first loops
        }
        cout << endl;

    }

    //cout << output << endl;

    return 0;
}

string bruteforce(string b)
{
    int length = b.length();
    for(int i = 0; i < length2; i++) //brute-force method for each letter in the alphabet
        {
                decrypt = ""; //clears the string at each iteration
                for(int j = 0; j < length; j++) //will print out each letter from the cipher
                {
                        decrypt[j] = ((int)b[j]+ i); //gives the decrypt string 
                                                         //the ASCII value for the cipher 
                                                         //for each iteration of i and shifts 
                                                         //it by 1 for each iteration
                        if((int)decrypt[j] > 90) //checks to see if the ASCII value is valid for each letter. If it is not, it will correct it
                        {
                                decrypt[j] = (int)decrypt[j] - 26;
                        }
            decrypt[j] = tolower(decrypt[j]);
                        cout << decrypt[j]; //outputs the key by the value it was shifted by
                }
                cout << endl; //creates a new line for the next iteration in the loop
        }
    return b;
}


//this function will encrypt the message using the affine function 7x + 8
char encrypt(char e)
{
    e = toupper(e); //converts the text to uppercase letters
    e = e - 65; //gives the ASCII value ranging from 0 to 25 based on the letter being passed
    e = (7 * e + 8) % 26; //the affine function 
    e = e + 65;
    if(e > 90) //if ASCII character is not in the English alphabet, the if statements will correct that
    {
        e = e - 26;
    }

    if(e < 65)
    {
        e = e + 26;
    }
    return e; //returns the values
}

//this function will decrypt the message using the affine function y = 5x + 12;
char ddecrypt(char d)
{
    d = toupper(d); //convers the text to uppercase letters if any of the letters are lowercase
    d = d - 65; //gives ASCII value ranging from 0 to 25 based on the letter being passed
    d = (d - 12); // starts off the y = 5x + 12 affine function
    if(d < 0) //checks to see if the value is negative and changes accordingly
    {
        d = d + 26;
    }
    d = (d * 21) % 26; //The inverse of 5 is 21 and then we take the remainder to see what value d gets

    d = d + 65; //Raises the ASCII value back up and we repeat the process from the encrypt function for the if statements
    if(d > 90)
    {
        d = d - 26;
    }

    if(d < 65)
    {
        d = d + 26;
    }
    d = tolower(d);
    return d; //returns the values
}

//After doing some calculations from the plain text "if"
//The values for Alpha and Beta were found
//Alpha is 9 and Beta is 10 and we know that the inverse of 9 is 3
//So the equation to encrypt would be y = 9x + 10
//So now we can use this equation to help us
//Decrypt the message
char affine(char f)
{
    f = toupper(f); //converts the text to uppercase letters just like we did use from the ddecrypt function
    f = f - 65; //gives ASCII value ranging from 0 to 25 based on the letter being passed
    f = (f - 10); //starts off the y = 9x + 10 affine function from our calculations
    if(f <  0) //checks to see if the value is negative and changes accordingly
    {
        f = f + 26;
    }
    f = (f * 3) % 26;
    f = f + 65; //Raises the ASCII value back up and we repeate the process from the encrypt function for the if statements
    if(f > 90)
    {
        f = f - 26;
    }

    if(f < 65)
    {
        f = f + 26;
    }
    f = tolower(f);
    return f; //returns the values
}

//This function will decrypt the message 
//TCABTIQMFHEQQMRMVMTMAQ for the equation
// y = 3x + b for some b
//We are going to decrypt the message with b
//starting from 0 all the way up to 25
//We are doing the same thing as we did in the affine
//function, but without knowing what b is
char affine2(char b, int beta)
{
    b = toupper(b); //Will convert the text to Uppercase letters
    b = b - 65; //gives ASCII value ranging from 0 to 25 based on the letter being passed
    b = b - beta; //starts off the y = 3x + b with beta starting from 0 up to 25
    if(b < 0) // checks to see if the value is negative and changes accordingly
    {
        b = b + 26;
    }

    b = (b * 9) % 26;
    b = b + 65; //raises the ASCII value back up and we repeat the process from the encrypt function for the if statements
    if(b > 90)
    {
        b = b - 26;
    }

    if(b < 65)
    {
        b = b + 26;
    }
    b = tolower(b);
    return b; //returns the values
}

Your function bruteforce.

I see that you set decrypt to be an empty string, so a string of size zero.

You then start reading and writing to decrypt[j]. But decrypt is a string of length zero. Writing to the jth element of a string of length zero means you're writing off the end of the string and over the top of some other memory.

I'd guess that in your Linux version, the memory you were reading and writing to was memory that belonged to your process and the OS was happy to let you do it. Maybe you were trashing other variables, maybe the Linux version didn't bother resizing the strings. I suspect that under windows, it's memory the OS is not happy to let you trash. The internals of how the compilers move strings around and handle memory and so on is up to them; the point is, you're reading from and writing to memory that isn't part of the string.

You can do youself a favour by replacing every string access like this:

somestring[i]

with this

somestring.at(i)

The first is unchecked; you are trusted and it doesn't check that you're witihin the string. The second takes longer but includes a check, and if you're out of the string, it will throw an exception and you'll know.

Member Avatar for TheFearful

So the function that is causing my runtime error is my bruteforce function?

Yes. It's wrong. That it worked on Linux was by chance.

Possibly other places as well. I see there are other places where you create a string of length zero and then start reading/writing the jth element of it.

Member Avatar for TheFearful

In that case, should I give the empty string a size of whatever the length of the message I am trying to encrypt/decrypt so that way I am not writing over the end of the string?

There are a lot of ways to solve this problem. You could make the string the right size at the start, you could add letters on the end using push_back, you could do a lot of things.

Don't use [] to read from or write to them.

Once you've fixed it, remove all that length=code. That's painful.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.