2

I have to write code for a random cipher problem. I have done it, but the program transforms only uppercase or lowercase (depending on what I choose) letters as input. What should I change so that the program transforms both upper and lower-case letters?

code:

   srand(time(0));     //seed for rand()
static char alphabet[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
string alph="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const int LENGTH=sizeof(alphabet)-1;     

int r;
char temp;
for (unsigned int i=0; i<LENGTH; i++)   //loop which shuffles the array
{
    r=rand() % LENGTH;  
    temp=alphabet[i];         
    alphabet[i] = alphabet[r];  
    alphabet[r]=temp;   
}

string text;
getline (cin, text);
for (unsigned int i=0; i<text.length(); i++)     //loop to encrypt
{
    if (isalpha(text[i]))
    {
        text[i]=alphabet[text[i] - 'A'];    //index alphabet with the value of text[i], adjusted to be in the range 0-25

    }
}
nenko182
  • 41
  • 7

2 Answers2

1

EDIT: Added full code (also for decryption of this substitution cipher)

Add second alphabet of lowercase characters and modify it in the same loop which shuffles array of first alphabet like:

temp=alphabet_of_lowerCase[i];         
alphabet_of_lowerCase[i] = alphabet_of_lowerCase[r];  
alphabet_of_lowerCase[r]=temp; 

Now in your encryption scheme just check if symbol is lowercase or uppercase letter with islower is isupper functions and use required alphabet array accordingly inside isalpha if branch:

if (islower()) {
   text[i]= alphabet_of_lowerCase[text[i] - 'a'];
}
else
   // your previous code

Full code:

static char alphabet[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static char text[] = "TEST";

void shuffleAlphabet() {

    srand(time(0));     //seed for rand()

    const int LENGTH = sizeof(alphabet)-1;

    int r;
    char temp;
    for (unsigned int i=0; i<LENGTH; i++)   //loop which shuffles the array
    {
        r=rand() % LENGTH;
        temp=alphabet[i];
        alphabet[i] = alphabet[r];
        alphabet[r]=temp;
    }

}

void cipher(int decrypt) {

    for (unsigned int i=0; i<strlen(text); i++)     //loop to encrypt
    {
        if (isalpha(text[i]))
        {
            if (!decrypt)
                text[i]=alphabet[text[i] - 'A'];    //index alphabet with the value of text[i], adjusted to be in the range 0-25
            else {
                int charPos = strchr(alphabet, text[i]) - alphabet; // calculate character position in cipher alphabet
                text[i]='A' + charPos; // and advance forward in standard alphabet by this position
            }
        }
    }

}

int main()
{
    printf("Text: %s\n", text);
    shuffleAlphabet();
    printf("Cipher alphabet: %s\n", alphabet);
    cipher(0);
    printf("Encrypted: %s\n", text);
    cipher(1);
    printf("Decrypted: %s\n", text);

    return 0;
}

So in general you need only to know cipher alphabet used to decipher encrypted text. Actually you don't have to even know cipher alphabet to decode encrypted text, because you can use frequency analysis for breaking almost all substitution ciphers (including XOR encryption). Unless ... key used in substitution cipher is with same length as size of original text and is always random,- in this case we will get unbreakable one-time pad.

Agnius Vasiliauskas
  • 10,935
  • 5
  • 50
  • 70
  • Ahh, this solves it! Thank you, wish I had thought of it earlier. Have a great day! – nenko182 Feb 02 '15 at 15:56
  • Also, would it be possible to decrypt a message using this random cipher? It confuses me as I don't have a key to the cipher so I have no idea how a decryption code should look like for this program. – nenko182 Feb 03 '15 at 00:50
  • I've updated my answer to include decryption part - check it out :-) – Agnius Vasiliauskas Feb 10 '15 at 12:23
0

You can use the std::transform() algorithm function, with a lambda that returns the upper or lower case character transformation.

#include <algorithm>
#include <cctype>
#include <string>
//...
std::string text;
//...
std::transform(text.begin(), text.end(), text.begin(), [](char c) 
  { return isupper(c)?tolower(c):toupper(c); });

Live Example: http://ideone.com/PJmc1b

The std::transform function is named transform for a reason, and the above is an example. We take the string, iterate over it, and "transform" each character from lower to upper (or vice-versa). The lambda function is the rule to apply to each character in the string.

PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45