如何解决时间: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;
}
在上面的代码中,我在减法之前添加了字母大小。模运算的行为类似于圆和角度。
注意:
-
字母被声明为
static const
,因为只有一个实例 (static
) 并且它们是只读的 (const
)。这有助于编译器优化代码和存储。 -
我相信使用字母比假设 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 举报,一经查实,本站将立刻删除。