0

I am trying to work out how I would be able to implement this autokey cipher and think that I have most of it worked out. The cipher is supposed to use a subkey style system using the characters positions in the alphabet.

Currently I am stuck on how to handle a few symbols " ;:,." when they are input as part of the encryption or decryption string and and not sure how to approach it as I am new to the language. Any guidance or direction would be wonderful. Posed the code and an example of how the cipher should work below.

Cipher Description: enter image description here

#include <iostream>
#include <string>
#include <assert.h>

using namespace std;

//Declares
char autokeyE(int, int);
char autokeyD(char);
char numToLetter(int);
int letterToNum(char);

int main()
{
    //Declares
    string inputText, finalText;
    int firstAlpha = 0;
    int key = 0;
    int option = 0;


    //First Values
    do
    {
        cout << "What operation would you like to do? Press '1' for Encrypt and '2' for Decrypt." << endl ;
        cin >> option;

        if (option == 1)
        {
            cout << "Please input your plain text to encrypt." << endl ;
            cin >> inputText;
            cout << "Please input your key to encrypt with." << endl;
            cin >> key;

            string finalText = "";

            firstAlpha = letterToNum(inputText[0]);
            finalText = numToLetter((firstAlpha + key) %26);
            //inputText[0] = finalText[0];

            for (int x = 1; x < inputText.length(); x++)
            {

                finalText += autokeyE(letterToNum(inputText[x-1]), letterToNum(inputText[x]));
            }
            cout << finalText << endl;
        }

        if (option == 2)
        {
            cout << "Please input your encrypted text to decrypt." << endl ;
            cin >> inputText;
            string finalText = "";

            firstAlpha = letterToNum(inputText[0]);
            finalText = numToLetter((firstAlpha + key) %26);

            for (int x = 1; x < inputText.length(); x++)
            {
                //cout << inputText[x]; Testing output
                finalText += autokeyD(inputText[x]);
            }
            cout << finalText << endl;
        }
    }
    while (!inputText.length() == 0);
}

char autokeyE(int c, int n)
{
    cout << "Keystream: " << n << " | Current Subkey: " << c << endl;

        int result = 0;
        //c = toupper(c);
        result = ((c + n) +26 )%26;
        cout << "C as a numtoletter: " << numToLetter(result) << " Result: " << result << endl;
        return numToLetter(result); 
    return c;
}

char autokeyD(char c)
{
    //Decrypting Shift -1
    if (isalpha(c))
    {
        c = toupper(c); 
        c = (((c - 65) - 1) % 26) + 65;
    }
    return c;
}

char numToLetter(int n)
{
    assert(n >= 1 && n <= 32);
    return "ABCDEFGHIJKLMNOPQRSTUVWXYZ ;:,."[n];  
}

int letterToNum(char n)
{
    if (isalpha(n))
    {
        n = toupper(n);
        return(int) n - 65; 
    }
    else 
    {
        cout << "REUTRNING A NON ALPHA CHARACTER AS: " << n << endl;
        return(int) n -30;
    }

}
Rishi
  • 1,387
  • 10
  • 14
xCROv
  • 1
  • How certain are you that this algorithm can handle non-alpha input? – user4581301 Nov 21 '17 at 05:51
  • As certain as someone who isn't advanced in the language can be! I believe the issue is really in the letterToNum function that I have created because im not sure how to translate those values into something the next character can use to encrypt and continue the process past a non alpha character. – xCROv Nov 21 '17 at 05:59
  • Note the P's values row. A is 0. T is 19. This makes sense as A is the first letter and T is the 20th and Z is 26th so I'd presume it has a value of 25. So what number do you assign to a character that isn't a letter and still abide by the given algorithm? You could pick values, say '.' = 16, '!' = 27, but that ruins the math used to produce C's values: P+Key mod 26. If the assignment is to define a new algorithm to handle non-letter input, cool, but if not, then your best option is to discard everything that isn't a letter. Note how there are no spaces in the given text. – user4581301 Nov 21 '17 at 06:09
  • That may be the best solution and what I was attempting to do with the If statement in letterToNum but I think it messes up the math for generating the rest of the encryption. Not sure though. I will try that. Thanks. – xCROv Nov 21 '17 at 06:19

2 Answers2

0

I don't understand your question, but I reckon the answer would be to do a back slash before each character that does not work, like so: "\;\:\,\." ( some of these may work, so only do it on the ones that don't)

Anonymous
  • 355
  • 2
  • 14
  • Sorry if it was a bit confusing. Currently when you run the program it will generate values for these corresponding to their place in the alphabet (a = 0, b=1, etc.). The issue is that the way the cipher works is that it uses the previous characters place to generate a encrypted text as shown in the picture I linked in the original post. My issues is trying to find a way to encrypt and be able to decrypt these without messing throwing a wrench in everything like what currently happens if you try a string like "attack:" as a string. It generates a value but it not useful. – xCROv Nov 21 '17 at 05:53
  • Ok then, but I suggest that you don't include them – Anonymous Nov 21 '17 at 06:03
0

You can handle symbols using isPunct in C++ such as:

if (isPunct(inputText[x]) {
    //do whatever it is you need to do
}
Jlegend
  • 531
  • 1
  • 6
  • 19