How can I do "rot-13 decode" in MFC? - c++

Well, I want to make a function which have encoding and decoding function.
So, I studied about "rot-13 encoding" and solved it like this:
char* szTemp = "Hello World";
for (int i = 0; i < strlen(szTemp); i++)
{
if (szTemp[i] >= 'a' && szTemp[i] <= 'm') szTemp[i] += 13;
else if (szTemp[i] >= 'A' && szTemp[i] <= 'M') szTemp[i] += 13;
else if (szTemp[i] >= 'n' && szTemp[i] <= 'z') szTemp[i] -= 13;
else if (szTemp[i] >= 'N' && szTemp[i] <= 'Z') szTemp[i] -= 13;
}
MessageBox(szTemp);
But it have some error. What is it? Anyone help me!

In MFC, it's all about the CString...
CString sTemp = "Hello World";
CString sResult = "";
int nLength = sTemp.GetLength();
char c;
for ( int i = 0 ; i < nLength ; ++i )
{
c = sTemp[i];
if (c>= 'a' && c<= 'm') c+= 13;
else if (c>= 'A' && c<= 'M') c+= 13;
else if (c>= 'n' && c<= 'z') c-= 13;
else if (c>= 'N' && c<= 'Z') c-= 13;
sResult += c;
}
AfxMessageBox( sResult );
It can also be done by accessing the buffer directly, in which case, you can use almost all of your original code. It looks something like this:
CString sTemp = "Hello World";
int nLength = sTemp.GetLength();
// Limit scope of szTemp since it is not usable after
// the call to ReleaseBuffer
{
char* szTemp = sTemp.GetBuffer();
for (int i = 0; i < nLength; i++)
{
if (szTemp[i] >= 'a' && szTemp[i] <= 'm') szTemp[i] += 13;
else if (szTemp[i] >= 'A' && szTemp[i] <= 'M') szTemp[i] += 13;
else if (szTemp[i] >= 'n' && szTemp[i] <= 'z') szTemp[i] -= 13;
else if (szTemp[i] >= 'N' && szTemp[i] <= 'Z') szTemp[i] -= 13;
}
sTemp.ReleaseBuffer();
}
AfxMessageBox( sTemp );
Hope that helps,
D*

Related

Affine cipher decryption, output differs for upper case and lower case

I have the problem when decrypting a plaintext using Affine cipher.
Encryption works fine, but applying the same logic for decryption of lower case/upper case characters returns different output.
Here is the output:
Encrypted Message is : ulctkbsjarizqhypgxofwnevmd ULCTKBSJARIZQHYPGXOFWNEVMD
Decrypted Message is: opqrstuvwxyzabcdefghijklmn ABCDEFGHIJKLMNOPQRSTUVWXYZ
I suspect it has something to do with retrieving of ASCII values, can someone correct me?
Here is my code:
#include<bits/stdc++.h>
using namespace std;
//Key values of a and b
const int a = 17;
const int b = 20;
string encryptMessage(string plainText)
{
string cipher = "";
for (int i = 0; i < plainText.length(); i++)
{
if(plainText[i]!=' ')
{
if ((plainText[i] >= 'a' && plainText[i] <= 'z') || (plainText[i] >= 'A' && plainText[i] <= 'Z'))
{
if (plainText[i] >= 'a' && plainText[i] <= 'z')
{
cipher = cipher + (char) ((((a * (plainText[i]-'a') ) + b) % 26) + 'a');
}
else if (plainText[i] >= 'A' && plainText[i] <= 'Z')
{
cipher = cipher + (char) ((((a * (plainText[i]-'A') ) + b) % 26) + 'A');
}
}
else
{
cipher += plainText[i];
}
}
else
{
cipher += plainText[i];
}
}
return cipher;
}
string decryptCipher(string cipher)
{
string plainText = "";
int aInverse = 0;
int flag = 0;
for (int i = 0; i < 26; i++)
{
flag = (a * i) % 26;
if (flag == 1)
{
aInverse = i;
}
}
for (int i = 0; i < cipher.length(); i++)
{
if(cipher[i] != ' ')
{
if ((cipher[i] >= 'a' && cipher[i] <= 'z') || (cipher[i] >= 'A' && cipher[i] <= 'Z'))
{
if (cipher[i] >= 'a' && cipher[i] <= 'z')
{
plainText = plainText + (char) ((((aInverse * (cipher[i]+ 'a') ) - b) % 26) + 'a');
}
else if (cipher[i] >= 'A' && cipher[i] <= 'Z')
{
plainText = plainText + (char) (((aInverse * ((cipher[i]+'A' - b)) % 26)) + 'A');
}
}
else
{
plainText += cipher[i];
}
}
else
plainText += cipher[i];
}
return plainText;
}
//Driver Program
int main(void)
{
string msg = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//Calling encryption function
string cipherText = encryptMessage(msg);
cout << "Encrypted Message is : " << cipherText<<endl;
//Calling Decryption function
cout << "Decrypted Message is: " << decryptCipher(cipherText);
return 0;
}
I have been thinking about this for some time and, although I can't provide a complete explanation, I have a couple of 'observations' that may be useful, plus a 'cheat' workaround.
First, although you say you use "the same logic for decryption of lower case/upper case," a character-wise alignment of the code from each of your decryption blocks shows that this isn't quite true:
plainText = plainText + (char) ((((aInverse * (cipher[i]+ 'a') ) - b) % 26) + 'a'); // Lower case
plainText = plainText + (char) (((aInverse * ((cipher[i]+'A' - b)) % 26)) + 'A'); // Upper case
So, 'fixing' the lower case code to be exactly analogous to the (working) code for upper case (and removing redundant parentheses) gives this:
if (cipher[i] >= 'a' && cipher[i] <= 'z')
{
plainText = plainText + (char)( ( (aInverse * (cipher[i] + 'a' - b) ) % 26 ) + 'a' );
}
else if (cipher[i] >= 'A' && cipher[i] <= 'Z')
{
plainText = plainText + (char)( ( (aInverse * (cipher[i] + 'A' - b) ) % 26 ) + 'A' );
}
However, this doesn't actually resolve the issue (it just changes it slightly), as the output then is as follows:
Encrypted Message is : ulctkbsjarizqhypgxofwnevmd ULCTKBSJARIZQHYPGXOFWNEVMD
Decrypted Message is : qrstuvwxyzabcdefghijklmnop ABCDEFGHIJKLMNOPQRSTUVWXYZ
The problem here is that the lowercase values are all 'rotated' by the value 16 - which looks suspiciously close to the value for a. Also, note that, although a is used in the encryption formula, it is not used in your decryption.
So, I have come up with the following workaround, assuming that (for reasons yet to be deduced) when decoding upper case values, this 16 is somehow lost in the bit-representation of the ASCII values:
if ((cipher[i] >= 'a' && cipher[i] <= 'z') || (cipher[i] >= 'A' && cipher[i] <= 'Z'))
{
int offset = ((cipher[i] - 'A') / 26) ? a - 1 : 0;
if (cipher[i] >= 'a' && cipher[i] <= 'z') {
plainText = plainText + (char)( ( (aInverse * (cipher[i] + 'a' - b) - offset ) % 26 ) + 'a' );
}
else if (cipher[i] >= 'A' && cipher[i] <= 'Z') {
plainText = plainText + (char)( ( (aInverse * (cipher[i] + 'A' - b) - offset ) % 26 ) + 'A' );
}
}
Note that your code can be further simplified/clarified using functions provided by the standard library and removing some 'redundant' checks:
for (int i = 0; i < cipher.length(); i++) {
if (isalpha(cipher[i])) {
int offset = islower(cipher[i]) ? a - 1 : 0;
int letter = islower(cipher[i]) ? 'a' : 'A';
plainText = plainText + (char)(((aInverse * (cipher[i] + letter - b) - offset) % 26) + letter);
}
else {
plainText += cipher[i];
}
}

Two parts of my decoding program aren't working as expected

I came here for help(with a more specific part) accouple days ago, but the solution I got didn't quite work. Basically I'm writing a program that serves 3 purposes: decodes a Rot 13 cypher, decodes a Rot 6 cypher, and put user input through an equation "x=2n-1" where n is the user input.
Rot 13 works fine, but Rot 6 outputs gibberish, and the equation outputs a letter (putting "8" gives you o instead of 15)
I know that this could be done in less functions, and I probably don't need an list, but this is for an assignment, and I need them
I know that I am not great at this, but any help would be great
#include <iostream>
#include <string>
#include <list>
#include <array>
using namespace std;
string coffeeCode(string input) { //Coffee code= 2n-1 where n=a number in a string
double index{};
input[index] = 2*input[index]-1;
return input;
};
string rot6(string input) {
int lower[] = { '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',' ' };
int upper[] = { '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' };
int inputSize = input.size(); // rot 6 rotates letters so that a{0}->g[6]
int index{}; // m[12]->s[18]
// n->t
while (index != inputSize) { // z->f
if (input[index] >= lower[0] && input[index] <= lower[19])
input[index] = input[index] + 6;
else if (input[index] >= lower[20] && input[index] <= lower[25])
input[index] = input[index] - 20;
else if (input[index] >= upper[0] && input[index] <= upper[19])
input[index] = input[index] + 6;
else if (input[index] <= upper[20] && input[index] <= upper[25])
input[index] = input[index] - 20;
index++;
}
return input;
}
string rot13(string input) { //Decodes into rot 13
int lower[] = { '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',' ' };
int upper[] = { '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' };
int inputSize = input.size();
int index{};
while (index != inputSize) {
if (input[index] >= lower[0] && input[index] <= lower[12])
input[index] = input[index] + 13;
else if (input[index] >= lower[13] && input[index] <= lower[25])
input[index] = input[index] - 13;
else if (input[index] >= upper[0] && input[index] <= upper[12])
input[index] = input[index] + 13;
else if (input[index] <= upper[13] && input[index] <= upper[25])
input[index] = input[index] - 13;
index++;
}
return input;
}
int main() {
string plaintext;
string ans13;
string ans6;
string ansCoffee;
cout << "Whats the message Spy Guy: ";
getline(cin, plaintext);
ans13 = rot13(plaintext);
ans6 = rot6(plaintext);
ansCoffee = coffeeCode(plaintext);
cout << "One of these is your decoded message" << endl << "In Rot 13: " << ans13 << endl << "In Rot 6: " << ans6 << endl
<< "In Coffee Code: " << ansCoffee << endl;
return 0;
}
Your best chance at understanding what you are doing is reading about how c++ handles characters, and what ASCII is.
[http://www.asciitable.com/]
Just a quick summary:
The ASCII table assigns every character in the english alphabet a number(or a code), and that number is what C++ actually stores in memory.
So, when you do char c = 'a' that is equivalent to doing char c = 97.
The ASCII table is pretty organised too, so all capital letters are in alphabetical order starting from 65(which is A) to 90(which is Z). The same is true for non capital letters, which go from 97 to 122, and for digits, which go from 48 to 57.
This can be used to determine what kind of character a variable is:
if ('a' <= input[index] && input[index] <= 'z') {
// It's lower case
}
if('A' <= input[index] && input[index] <= 'Z') {
// It's upper case
}
Note that when you put a singe character in single quotes the compiler will replace it with it's ASCII code, so you don't actually need to memorize the table. Think about how you could construct an if to determine whether a character is a digit.
Here is how I would implement the rot6. It may not bet the best, but I think it's alright.
string rot6(string input) {
for (int index = 0; index < input.size(); ++ index) {
if ('a' <= input[index] && input[index] <= 'z') { // It's lower case
input[index] = 'a' + ((input[index] - 'a') + 6) % 26;
}
else if ('A' <= input[index] && input[index] <= 'Z') { // It's upper case
input[index] = 'A' + ((input[index] - 'A') + 6) % 26;
}
else if ('0' <= input[index] && input[index] <= '9') { // It's a digit
input[index] = '0' + ((input[index] - '0') + 6) % 10;
}
else { // It's an error
return "Error, bad input!";
}
}
return input;
}

getline() isn't working in code

Yesterday I started developing a encrypting machine, that works like a Caesar cipher. You put a message (e.g., HELLO), choose a key value (e.g., 3) and the result is KHOOR (3 letters forward).
The problem is that, if I use "cin >> msg;" I can only codify one word. If I use "getline (cin, msg);", the code doesn't work. Maybe it's a simple problem, but I can't solve it... :(
string msg;
int a, b, i, key_value;
char c;
cout << "WRITE YOUR MESSAGE:" << endl;
cin >> msg; //HERE IS THE PROBLEM!!!
system ("cls");
cout << "PUT A KEY VALUE:" << endl;
cin >> key_value;
system ("cls");
cout << "THE CODIFIED MESSAGE IS:" << endl;
for (i=0; i < msg.length(); i++) {
if (msg[i] == 'A') a = 1;
if (msg[i] == 'B') a = 2;
if (msg[i] == 'C') a = 3;
if (msg[i] == 'D') a = 4;
if (msg[i] == 'E') a = 5;
if (msg[i] == 'F') a = 6;
if (msg[i] == 'G') a = 7;
if (msg[i] == 'H') a = 8;
if (msg[i] == 'I') a = 9;
if (msg[i] == 'J') a = 10;
if (msg[i] == 'K') a = 11;
if (msg[i] == 'L') a = 12;
if (msg[i] == 'M') a = 13;
if (msg[i] == 'N') a = 14;
if (msg[i] == 'O') a = 15;
if (msg[i] == 'P') a = 16;
if (msg[i] == 'Q') a = 17;
if (msg[i] == 'R') a = 18;
if (msg[i] == 'S') a = 19;
if (msg[i] == 'T') a = 20;
if (msg[i] == 'U') a = 21;
if (msg[i] == 'V') a = 22;
if (msg[i] == 'W') a = 23;
if (msg[i] == 'X') a = 24;
if (msg[i] == 'Y') a = 25;
if (msg[i] == 'Z') a = 26;
b = a + key_value;
if (b > 26) b -= 26;
if (b == 1) c = 'A';
if (b == 2) c = 'B';
if (b == 3) c = 'C';
if (b == 4) c = 'D';
if (b == 5) c = 'E';
if (b == 6) c = 'F';
if (b == 7) c = 'G';
if (b == 8) c = 'H';
if (b == 9) c = 'I';
if (b == 10) c = 'J';
if (b == 11) c = 'K';
if (b == 12) c = 'L';
if (b == 13) c = 'M';
if (b == 14) c = 'N';
if (b == 15) c = 'O';
if (b == 16) c = 'P';
if (b == 17) c = 'Q';
if (b == 18) c = 'R';
if (b == 19) c = 'S';
if (b == 20) c = 'T';
if (b == 21) c = 'U';
if (b == 22) c = 'V';
if (b == 23) c = 'W';
if (b == 24) c = 'X';
if (b == 25) c = 'Y';
if (b == 26) c = 'Z';
cout << c;
}
So your code works fine: http://ideone.com/lBhD78
If you're trying to accept more than 1 word the simple extraction operator will not work however. Which is probably what you're asking about. In this case you will want to use getline. Like this for instance:
getline(cin, msg, '\n');
So I'm not certain what you're complaining about, however this could be much improved by:
Being case-insensitive
Only modifying alpha-characters
You could accomplish this by doing something like:
transform(cbegin(msg), cend(msg), ostream_iterator<char>(cout), [&](unsigned char i){
if(isalpha(i)) {
const auto a = islower(i) ? 'a' : 'A';
i = (i - a + key_value) % 26 + a;
}
return i; });
I've written a Live Example complete with getline.
You have to be carefull to write questions.
BUT, without being clear what you mean, the answer is:
When you read cin>>s, by default, you are considering the data are separated by "white spaces". So, it skips spaces and read the string until a new space or end of input.
If you have problems with getline, probably the problem is before the code you are shown. If you read a value with, for example, cin>>integer, you push newline key at the end of the input, but this character is still in the stream. If the following line in your code es getline, probably you will read an empty line.
In the first item you find why you current code works, in the second one, why your getline-version doesn't.

Wrapping chars in caesar cipher encode

Can anyone please explain me how this wrapping of chars between a-to-z and A-to-Z happening in Caesar shift code?
k %= 26;
for(int i = 0; i < n; i++){
int c = s[i];
if(c >= 'a' && c <= 'z'){
c += k;
if( c > 'z'){
c = 96 + (c % 122); // wrapping from z to a?
}
}
else if(c >= 'A' && c <= 'Z'){
c += k;
if(c > 'Z'){
c = 64 + (c % 90);
}
}
cout << (char)c;
}
K is amount of shift and c is a char of string s.
Is there any better way to do the same?
Lets make a couple changes to the code and it is easier to see what is going on
for(int i = 0; i < n; i++){
int c = s[i];
if(c >= 'a' && c <= 'z'){
c += k;
if( c > 'z'){
c = 'a' + (c % 'z') - 1; // wrapping from z to a?
}
}
else if(c >= 'A' && c <= 'Z'){
c += k;
if(c > 'Z'){
c = 'A' + (c % 'Z') - 1;
}
}
cout << (char)c;
}
So in c = 'a' + (c % 'z') - 1; if c is larger than z then we mod c by z(122) to get how many characters from a we need to go. The same thing is going on with the upper case letters. I am subtracting one here as we are starting at a instead of the character before a like you original code does.

Code compiles, however crashes after start(rot13) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
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.
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.
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);