Reputation: 69
So I am making a substitution cipher, where both Encipher and Decipher are handled by the same function after having specific parameters passed by separate respective functions. For some reason, it is working to encrypt, but it won't decrypt my message. In my code, a 'cipherAlphabet' is created from a keyword, and used along with a normal alphabet to decrypt/encrypt, while also printing to a text file. The decrypted code however is output the exact same as the encrypted code and I can't seem to understand why. Any thoughts or ideas are appreciated, thanks!
static string Cipher(string input, string oldAlphabet, string newAlphabet,
string &output)
{
output = "";
int inputLen = input.size();
if (oldAlphabet.size() != newAlphabet.size())
{
cout << "New alphabet doesn't match size of original alphabet";
exit(1);
}
for (int i = 0; i < inputLen; ++i)
{
int oldCharIndex = oldAlphabet.find(tolower(input[i]));
if (oldCharIndex >= 0)
output += isupper(input[i]) ? toupper(newAlphabet[oldCharIndex]) : newAlphabet[oldCharIndex];
else
output += input[i];
}
return output;
}
static string Encipher(string input, string cipherAlphabet, string &output)
{
string plainAlphabet = "abcdefghijklmnopqrstuvwxyz";
return Cipher(input, plainAlphabet, cipherAlphabet, output);
}
static string Decipher(string input, string cipherAlphabet, string &output)
{
string plainAlphabet = "abcdefghijklmnopqrstuvwxyz";
return Cipher(input, cipherAlphabet, plainAlphabet, output);
}
string encoder(string key)
{
string encoded = "";
// This array represents the
// 26 letters of alphabets
bool arr[26] = {0};
// This loop inserts the keyword
// at the start of the encoded string
for (int i = 0; i < key.size(); i++)
{
if (key[i] >= 'A' && key[i] <= 'Z')
{
// To check whether the character is inserted
// earlier in the encoded string or not
if (arr[key[i] - 65] == 0)
{
encoded += key[i];
arr[key[i] - 65] = 1;
}
}
else if (key[i] >= 'a' && key[i] <= 'z')
{
if (arr[key[i] - 97] == 0)
{
encoded += key[i] - 32;
arr[key[i] - 97] = 1;
}
}
}
// This loop inserts the remaining
// characters in the encoded string.
for (int i = 0; i < 26; i++)
{
if (arr[i] == 0)
{
arr[i] = 1;
encoded += char(i + 65);
}
}
return encoded;
}
string removeDuplicate(string str)
{
set<char> S, Sd;
string duplicates = "";
string reduced = "";
for (char c : str)
{
if (S.insert(c).second)
reduced += c;
else if (Sd.insert(c).second)
duplicates += c;
}
int length = duplicates.length();
for (int i = 0; i < length; i++)
{
for (int j = 0; j < str.length(); j++)
{
str.erase(std::remove(str.begin(), str.end(), duplicates[i]),
str.end());
}
}
return str;
}
int main(int argc, char **argv)
{
string keyword1;
if (argc > 2)
{
cout << "Invalid input. There should only be 1 input (the keyword)." << endl;
exit(1);
}
else
{
keyword1 = argv[1];
}
string keyword = removeDuplicate(keyword1);
ifstream inFile("plaintext.txt");
ofstream outFile("ciphertext.txt");
ofstream outFile1("decrypted.txt");
inFile.open("plaintext.txt");
std::string content((std::istreambuf_iterator<char>(inFile)),
(std::istreambuf_iterator<char>()));
inFile.close();
string cipherAlphabet = encoder(keyword);
string cipherText;
string plainText;
outFile << Encipher(content, cipherAlphabet, cipherText);
outFile.close();
outFile1 << Decipher(cipherText, cipherAlphabet, plainText);
outFile1.close();
}
Upvotes: 0
Views: 105
Reputation: 75062
The string cipherAlphabet
contains only uppercase alphabets.
On the other hand, in the line
int oldCharIndex = oldAlphabet.find(tolower(input[i]));
it is searching for lowercase alphabets or non-alphabet characters.
Therefore, there will be no match.
Adding
if (oldCharIndex < 0) oldCharIndex = oldAlphabet.find(toupper(input[i]));
after the line to search for uppercase alphabets will fix the problem.
Upvotes: 1