微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

时间:2019-05-06 标签:c++caesar cipherdecoded麻烦

如何解决时间:2019-05-06 标签:c++caesar cipherdecoded麻烦

我正在尝试实现一个程序来读取具有凯撒密码加密的文本文件。我的程序的目的是解码它。使用我的代码,它只读取文件,不解码任何内容。我哪里错了? 它会回显文件,但不会对其进行解码。我认为我的逻辑在 CaesarCipher 函数的末尾有缺陷

#include <iostream>         //for standard I/O
#include <fstream>          //necessary for file input
#include <string>           //necessary for fileName input

using namespace std;

void Printheading ();           //prototype for printing the initial heading
char PrintMenu ();              //prototype for printing menu and gaining user's choice
void OpenFile (ifstream &);     //prototype for opening file
void CaesarCipher (ifstream &); //prototype for performing a caesar decryption
//void SubCipher (ifstream &);  //prototype for performing a substitution decryption

const int ALPHA_SIZE = 26;
typedef char AlphaArray[ALPHA_SIZE];        //alphabet array with 26 elements
AlphaArray realAlphas;
AlphaArray encryptionArray;
ifstream inFile;



int main()
{
char choice;            //menu choice from user
ifstream inFile;        //opens file
string fileName;        //user inputs name of file
bool condition = true;

Printheading();         // prints heading

while(condition)
{
    choice = PrintMenu();       //passes choice to printMenu function
    switch(choice)
    {
        case 'C':                           //choice for caesar substitution
        case 'c': cout << choice << endl;
            OpenFile(inFile);
            CaesarCipher (inFile);
            break;
        case 'S':                           //choice for substitution cipher
        case 's': cout << choice << endl;
            OpenFile(inFile);
            //SubCipher(inFile);
            break;
        case 'Q':                           //choice for quitting the program
        case 'q': condition = false;        //prints closing message when false
            cout << "***********************************************" << endl
                 << "\tThank you for using the DECRYPTER!" << endl
                 << "***********************************************" << endl << endl;
            break;
        default:
            //default statement for incorrect input
            cout << "Not a valid choice. Try again." << endl;
            break;
    }

}

return 0;
}

void Printheading ()    //prints heading for decryption program
{
cout << "***********************************************" << endl
     << "\t Welcome to The DECRYPTER!\t\t" << endl
     << endl
     << " You have the option of performing either a" << endl
     << "\t  Caesar decryption or " << endl
     << "\t  a Substitution decryption" << endl
     << endl
     << " You will be asked for a file to be decoded." << endl
     << endl
     << " The DECRYPTER will then echoprint one line " << endl
     << " of your encoded text from your specified file" <<endl
     << " followed by the same text decoded." << endl << endl
     << "***********************************************" << endl
     << endl
     << endl;
}

char PrintMenu ()       //function for displaying menu and gathering user's input
{
char userChoice;    //menu choice from user

//menu for user input
cout << "What would you like to do?" << endl
     << "To decode a text file using the Caesar cipher,press c" << endl
     << "To decode a text file using the substitution cipher,press s" << endl
     << "To quit decoding,press q" << endl
     << "What is your selection ? ";
cin >> userChoice;

while(userChoice != 'C' && userChoice != 'c' && userChoice != 'S' && userChoice != 's' && userChoice != 'Q' && userChoice != 'q')
{
    cout << "Please re-enter a valid menu choice: ";    //prompts user to input choice until it is valid
    cin >> userChoice;
}

return userChoice;              //return user's menu choice
}

void OpenFile (ifstream & infile)
{
string fileName;                //file input from user
cout << endl;
cout << "Please enter the file name to decode -> " << endl;      //asks for file name from user
cin >> fileName;                                                 //user file name
inFile.clear();
inFile.open(fileName.c_str());


while (!inFile)     //loop for if file doesnt exist
{
    cout << "File doesn't exist. Try again: " << endl;
    cin >> fileName;
 
void CaesarCipher (ifstream & infile)
{
char ch,temp;
for (int i = 0; i < 26; i++)
{
    realAlphas[i] = 65 + i;
}

int caesarConstant = 4;
for (int i = 0; i < 26; i++)
{
    encryptionArray[i] = realAlphas[(i + caesarConstant) % ALPHA_SIZE];
}

cout << "Original alphabet: " << realAlphas << endl;
cout << "Encrypted alphabet: " << encryptionArray << endl;
cout << endl;


int i;
while (inFile)
{
    if (!inFile.eof())
    {
        ch = inFile.get();
        cout << ch;
        for (i = 0; i < 26; i++)
        {
            encryptionArray[i] = realAlphas[i];
        }
        if (islower(encryptionArray[i]))
        {
            encryptionArray[i] = (encryptionArray[i] - 'a' + caesarConstant) % 26 + 'a';
        } else if (isupper(encryptionArray[i])) {
            encryptionArray[i] = (encryptionArray[i] - 'A' + caesarConstant) % 26 + 'A';
        }

    }
}


}

解决方法

对于凯撒密码解码,您需要减去以生成原始字符。

char decrypt(char c)
{
    static const std::string lower_case_alphabet = "abcdefghijklmnopqrstuvwxyz";
    static const std::string upper_case_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    std::string::size_type position = lower_case_alphabet.find(c);
    if (position == std::string::npos)
    {
       // character is not lower case.
       position = upper_case_alphabet.find(c);
       if (position == std::string::npos)
       {
          return c;
       }
       else
       {
           static const unsigned int alphabet_size = upper_case_alphabet.size();
           char decrypted = ((c + alphabet_size) - ENCRYPTION_KEY) % alphabet_size;
           decrypted = upper_case_alphabet[decrypted];
           return decrypted;
       }
   }
   static const unsigned int alphabet_size = lower_case_alphabet.size();
   char decrypted = ((c + alphabet_size) - ENCRYPTION_KEY) % alphabet_size;
   decrypted = lower_case_alphabet[decrypted];
   return decrypted;
}

在上面的代码中,我在减法之前添加了字母大小。模运算的行为类似于圆和角度。

注意:

  1. 字母被声明为 static const,因为只有一个实例 (static) 并且它们是只读的 (const)。这有助于编译器优化代码和存储。

  2. 我相信使用字母比假设 ASCII 编码(例如 65)更易于移植。您可以轻松更改字母表而无需更改代码,功能相同。

,

Here's 一个完整的程序,它进行加密和解密,以验证在加密然后解密后,我们得到相同的文件。

#include <fstream>
#include <iostream>
#include <string>

int main(int,char*[])
{
    //Create a dummy file to test the algo
    std::ofstream test("test.txt");
    if(!test.is_open()) {
        std::cout<<"failed to open test.txt";
    }
    test<<"  THis Is A tEst fILez\n";
    test.close();

    //Now open the file for operation
    std::fstream file("test.txt");
    if(!file.is_open()) {
        std::cout<<"Error\n";
        return -1;
    }
    std::string line;

    //Verify Contents
    // std::cout<<"Initial contents of the file\n";
    file.clear();
    file.seekg(0);
    while(std::getline(file>>std::ws,line)) {
        std::cout<<line<<'\n';
    }

    const int CAESAR_CONSTANT = 2;
    char readChar;

    //Encryption
    file.clear();
    file.seekg(0);
    while(file>>std::ws>>readChar) {
        if(std::isalpha(readChar)) {
            char baseChar = std::islower(readChar) ? 'a' : 'A';
            file.unget();
            file<<(char((readChar - baseChar + CAESAR_CONSTANT) % 26 + baseChar));
        }
    }

    //Verify Contents of encrypted file
    // std::cout<<"\n\nEncrypted contents of the file\n";
    file.clear();
    file.seekg(0);
    while(std::getline(file>>std::ws,line)) {
        std::cout<<line<<'\n';
    }

    //Decryption
    file.clear();
    file.seekg(0);
    while(file>>std::ws>>readChar) {
        if(std::isalpha(readChar)) {
            char baseChar = std::islower(readChar) ? 'a' : 'A';
            file.unget();
            char offset = readChar - baseChar - CAESAR_CONSTANT;
            if(offset < 0) {
                offset += 26;
            }
            file<<(char(offset + baseChar));
        }
    }

    //Verify Contents of decrypted file
    // std::cout<<"\n\nDecrypted contents of the file\n";
    file.clear();
    file.seekg(0);
    while(std::getline(file>>std::ws,line)) {
        std::cout<<line<<'\n';
    }
}

输出:

这是一个测试文件

VJku Ku C vGuv hKNgb

这是一个测试文件

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。