Solved

Simple Character Substitution Encryption

Posted on 2012-04-02
10
920 Views
Last Modified: 2012-04-03
I am trying to make my own simple encryption program to encrypt and decrypt a string.

The string will consist of only numbers. I will be using my own simple substitution method, which is as follows:



Plain alphabet  0 1 2 3 4 5 6 7 8 9
Cipher alphabet 2 4 5 0 8 9 1 3 6 7


Here is my encryption table:
Encryption Substitution Table

Let's assume we encrypt the password: 456

The encrypted text would be: 891 ( using our cipher alphabet ), right?


That is the program I am trying to write.

Here is the skeleton program I have so far, and I stripped it down to this because I am running into errors trying to manipulate the string characters.

Can someone help me with this simple example I can expand on?

Thanks!

#include <iostream>
#include <string>

using namespace std;

//---------------------------------------------------------------------------
// Global Variables
//---------------------------------------------------------------------------

/* This is the correct DECRYPTED password */
string correctNumber("456");


/* String var to hold users guess at password.
   This variables value will need to be run through
   the DECRYPT function to see if it matches the value
   of correctNumber
 */
string guess;

/* This is the encrypted password that will be
   built and encrypted based upon what the user
   types in. This will ultimately be compared to
   the encrypted version of correctNumber
*/
string userBuiltPassword;

//---------------------------------------------------------------------------
// Function Prototypes
//---------------------------------------------------------------------------
string encryptString(string strToEncrypt);
string decryptString(string strToDecrypt);
//---------------------------------------------------------------------------

int main()
{
    cout << "The password has been generated! You need to guess it." << endl;
    cout << "Enter password: ";
    cin >> guess;

    string tempEnc  = encryptString(guess);         // Get encrypted version of user guess
    string tempCorr = encryptString(correctNumber); // Get encrypted version of correct

    if(tempEnc == tempCorr)
    {

       cout << "You cracked the code!" << endl;

    } else
    {
        cout << "Incorrect. You lose." << endl;
    }

    return 0;
}
//---------------------------------------------------------------------------
// Functions
//---------------------------------------------------------------------------

/**
* Encrypts a string (using a global constant key)
*
* Takes a string and returns the encrypted version of the string.
* The string is generated using a very simple character substitution
* method.
*
* @param        string      strToEncrypt      String to encrypt
* @return       string      strEnc            Encrypted string
*
*/
string encryptString(string strToEncrypt)
{

    string strEnc;

    return strEnc;
}

/**
* Decrypts a string
*
* Takes a string and returns the decrypted version of the string.
* The string is generated using a very simple character substitution
* method.
*
* @param        string      strToDecrypt      String to decrypt
* @return       string      strDec            Decrypted string
*
*/
string decryptString(string strDec)
{
    string decString;

    return decString;
}

Open in new window

0
Comment
Question by:edvinson
  • 5
  • 5
10 Comments
 
LVL 53

Expert Comment

by:Infinity08
ID: 37798162
What errors are you running into ?

What did you try ? How far did you get ?
0
 
LVL 1

Author Comment

by:edvinson
ID: 37798271
Stripping this down to it's most simplest....

Let's assume the correct plain text is 0...

this code is not working:

#include <iostream>
#include <string>

using namespace std;

//---------------------------------------------------------------------------
// Global Variables
//---------------------------------------------------------------------------

/* This is the correct DECRYPTED password */
string correctNumber("0");

/* Not sure if we need this, or how to use this in my solution,
   however, something like this seems to make sense.
*/
int plainIntArray [] = {0,1,2,3,4,5,6,7,8,9};
int encIntArray   [] = {2,4,5,0,8,9,1,3,6,7};


/* String var to hold users guess at password.
   This variables value will need to be run through
   the DECRYPT function to see if it matches the value
   of correctNumber
 */
string guess;

/* This is the encrypted password that will be
   built and encrypted based upon what the user
   types in. This will ultimately be compared to
   the encrypted version of correctNumber
*/
string userBuiltPassword;

//---------------------------------------------------------------------------
// Function Prototypes
//---------------------------------------------------------------------------
string encryptString(string strToEncrypt);

//---------------------------------------------------------------------------

int main()
{
    cout << "The password has been generated! You need to guess it." << endl;
    cout << "Enter password: ";
    cin >> guess;

    string tempEnc  = encryptString(guess);
    string tempCorr = encryptString(correctNumber); // Get encrypted version of correct



    if(tempEnc == tempCorr)
    {

       cout << "You cracked the code!" << endl;

    } else
    {
        cout << "Incorrect. You lose." << endl;
    }

    return 0;
}
//---------------------------------------------------------------------------
// Functions
//---------------------------------------------------------------------------

/**
* Encrypts a string (using a global constant key)
*
* Takes a string and returns the encrypted version of the string.
* The string is generated using a very simple character substitution
* method.
*
* @param        string      strToEncrypt      String to encrypt
* @return       string      strEnc            Encrypted string
*
*/
string encryptString(string strToEncrypt)
{

    // Loop through all characters of parameter
    for(int i = 0; i<= strToEncrypt.length(); i++)
    {

        // Check for "0"
        if(strToEncrypt.substr(i,1) == "0")
        {

            userBuiltPassword.substr(i,1) = "2";

        }

    }



    return userBuiltPassword;
}

Open in new window



I know I am close, but new to C++ , so probably not as close as I think! lol
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 37798342
>> 83 :      for(int i = 0; i<= strToEncrypt.length(); i++)

The characters in the string are starting at index 0, and ending at index (strToEncrypt.length() - 1). Make sure not to read too much.


>> 90 :              userBuiltPassword.substr(i,1) = "2";

That's not really how things work with std::string's.

Try something more like this :

        userBuiltPassword += "2";

which would add "2" to the end of the existing string (given that you start with an empty string).
0
 
LVL 1

Author Comment

by:edvinson
ID: 37798384
hmmm, not working.

As expected, this simple problem is proving more difficult than expected.


In psuedocode, I want to:

1. encrypt the plain text correct number 0 , which would be: 2

2. and simply compare that to the number entered by the user.

I still don't see why my code is not working?

And not only that, I need to know how to check for more than one number, which would include arrays, right? And again, in my code, I don't see where I am going wrong.

Can you post some working code as proof of concept for your solution? I simply can't get it to work!

Ugh...
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 37798404
>> I still don't see why my code is not working?

I can't see it either, since you seem to have forgotten to post the new code ;)
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 1

Author Comment

by:edvinson
ID: 37798471
Here is latest code, incorporating your suggestion:

#include <iostream>
#include <string>

using namespace std;

//---------------------------------------------------------------------------
// Global Variables
//---------------------------------------------------------------------------

/* This is the correct DECRYPTED password */
string correctNumber("0");

/* Not sure if we need this, or how to use this in my solution,
   however, something like this seems to make sense.
*/
int plainIntArray [] = {0,1,2,3,4,5,6,7,8,9};
int encIntArray   [] = {2,4,5,0,8,9,1,3,6,7};


/* String var to hold users guess at password.
   This variables value will need to be run through
   the DECRYPT function to see if it matches the value
   of correctNumber
 */
string guess;

/* This is the encrypted password that will be
   built and encrypted based upon what the user
   types in. This will ultimately be compared to
   the encrypted version of correctNumber
*/
string userBuiltPassword;

//---------------------------------------------------------------------------
// Function Prototypes
//---------------------------------------------------------------------------
string encryptString(string strToEncrypt);

//---------------------------------------------------------------------------

int main()
{
    cout << "The password has been generated! You need to guess it." << endl;
    cout << "Enter password: ";
    cin >> guess;

    string tempEnc  = encryptString(guess);
    string tempCorr = encryptString(correctNumber);; // Get encrypted version of correct



    if(tempEnc == tempCorr )
    {

       cout << "You cracked the code!" << endl;

    } else
    {
        cout << "Incorrect. You lose." << endl;
    }

    return 0;
}
//---------------------------------------------------------------------------
// Functions
//---------------------------------------------------------------------------

/**
* Encrypts a string (using a global constant key)
*
* Takes a string and returns the encrypted version of the string.
* The string is generated using a very simple character substitution
* method.
*
* @param        string      strToEncrypt      String to encrypt
* @return       string      strEnc            Encrypted string
*
*/
string encryptString(string strToEncrypt)
{

    // Loop through all characters of parameter
    for(int i = 0; i<= strToEncrypt.length(); i++)
    {

        // Check for "0"
        if(strToEncrypt.substr(i,1) == "0")
        {

              userBuiltPassword += "2";

        }

        // Check for "2"
        if(strToEncrypt.substr(i,1) == "2")
        {

              userBuiltPassword += "0";

        }

    }



    return userBuiltPassword;
}

Open in new window



Not working still..
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 37798491
I'm not sure why you're translating a 2 into a 0 - that's not according to your substitution alphabet.

But the real issue is because of what I said earlier :

>> (given that you start with an empty string).

That was an important pre-condition for the approach to work : userBuiltPassword needs to be empty at the start of the encryptString function.

But, since you are using a global variable for it, and call the same function more than once, the second time the function is called, userBuiltPassword is not empty.

Why did you use a global variable in the first place ? Why not a local variable ?
0
 
LVL 1

Author Comment

by:edvinson
ID: 37799302
I think I have it working, could you please double check?

#include <iostream>
#include <string>

using namespace std;

//---------------------------------------------------------------------------
// Global Variables
//---------------------------------------------------------------------------

/* This is the correct DECRYPTED password */
string correctNumber("240");

/* Not sure if we need this, or how to use this in my solution,
   however, something like this seems to make sense.
*/
int plainIntArray [] = {0,1,2,3,4,5,6,7,8,9};
int encIntArray   [] = {2,4,5,0,8,9,1,3,6,7};


/* String var to hold users guess at password.
   This variables value will need to be run through
   the DECRYPT function to see if it matches the value
   of correctNumber
 */
string guess;

/* This is the encrypted password that will be
   built and encrypted based upon what the user
   types in. This will ultimately be compared to
   the encrypted version of correctNumber
*/
string userBuiltPassword;

//---------------------------------------------------------------------------
// Function Prototypes
//---------------------------------------------------------------------------
string encryptString(string strToEncrypt);
DWORD GetSerial();
//---------------------------------------------------------------------------

int main()
{
    cout << "The password has been generated! You need to guess it." << endl;
    cout << "Enter password: ";
    cin >> guess;

    string tempEnc  = guess;

    string tempCorr = encryptString(correctNumber); // Get encrypted version of correct



    if(tempEnc == tempCorr )
    {

       cout << "You cracked the code!" << endl;

    } else
    {
        cout << "Incorrect. You lose." << endl;
    }

    return 0;
}
//---------------------------------------------------------------------------
// Functions
//---------------------------------------------------------------------------

/**
* Encrypts a string (using a global constant key)
*
* Takes a string and returns the encrypted version of the string.
* The string is generated using a very simple character substitution
* method.
*
* @param        string      strToEncrypt      String to encrypt
* @return       string      strEnc            Encrypted string
*
*/
string encryptString(string strToEncrypt)
{

    string returnString;

    // Loop through all characters of parameter
    for(int i = 0; i<= strToEncrypt.length(); i++)
    {



        // Check for "0"
        if(strToEncrypt.substr(i,1) == "0")
        {

              returnString += "2";

        }

        // Check for "1"
        if(strToEncrypt.substr(i,1) == "1")
        {

              returnString += "4";

        }

        // Check for "2"
        if(strToEncrypt.substr(i,1) == "2")
        {

              returnString += "5";

        }

        // Check for "3"
        if(strToEncrypt.substr(i,1) == "3")
        {

              returnString += "0";

        }

        // Check for "4"
        if(strToEncrypt.substr(i,1) == "4")
        {

              returnString += "8";

        }

        // Check for "5"
        if(strToEncrypt.substr(i,1) == "5")
        {

              returnString += "9";

        }

        // Check for "6"
        if(strToEncrypt.substr(i,1) == "6")
        {

              returnString += "1";

        }

        // Check for "7"
        if(strToEncrypt.substr(i,1) == "7")
        {

              returnString += "3";

        }

                    // Check for "8"
        if(strToEncrypt.substr(i,1) == "8")
        {

              returnString += "6";

        }

        // Check for "9"
        if(strToEncrypt.substr(i,1) == "9")
        {

              returnString += "7";

        }

    }



    return returnString;
}

Open in new window


I know there is an easier way, but it appears to work. Can you just double check and offer suggestions?

Thanks.
0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 500 total points
ID: 37799523
Some suggestions :

(a) you can avoid the use of substr by iterating over the characters of the string (see eg. http://www.cplusplus.com/reference/string/string/begin/).

(b) instead of using single character string literals, try working with character literals instead (ie. 'a' instead of "a"). Other code will have to be changed too of course when making this switch.

(c) you have your substitution alphabet in the encIntArray array at the top. Why not use it ? Take a character from the plaintext string, convert it to its integer value, use it as the index into that array, get the integer value found there, and use it as the encrypted value.

(d) you still have quite a few global variables that don't need to be global. As a rule, keep the scope of your variables as small as possible, and only as big as they need to be.

(e) in your current code, the user has to enter the encrypted password, not the plaintext password. Is that intentional ?
0
 
LVL 1

Author Closing Comment

by:edvinson
ID: 37804115
I agree with your solution suggestions.

Thank you very much,
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now