【问题标题】:Caesar cipher program in c++c++中的凯撒密码程序
【发布时间】:2013-10-28 23:28:27
【问题描述】:

我正在尝试用 C++ 编写一个凯撒密码程序。我使用了四个函数,一个用于选择 shift key ,两个用于加密和解密,最后一个用于实现凯撒密码,使用输入文件读取文本并将加密或解密的文本输出到输出文件中。我正在尝试运行代码,但它正在崩溃。我认为问题出在凯撒函数内部。但我不知道究竟是什么。有任何想法吗?这是我的代码:

#include <iostream>
#include <fstream>
using namespace std;

int chooseKey()
{
    int key_number;
    cout << "Give a number from 1-26: ";
    cin >> key_number;

    while(key_number<1 || key_number>26)
    {
        cout << "Your number have to be from 1-26.Retry: ";
        cin >> key_number;  

    }
    return key_number;
}

void encryption(char *w, char *e, int key){

    char *ptemp = w;


    while(*ptemp){

        if(isalpha(*ptemp)){

        if(*ptemp>='a'&&*ptemp<='z')  
         {  
             *ptemp-='a';  
             *ptemp+=key;  
             *ptemp%=26;  
             *ptemp+='A';  
         }  


        }
        ptemp++;
    }

    w=e;

}

void decryption (char *e, char *w, int key){
    char *ptemp = e;


    while(*ptemp){

        if(isalpha(*ptemp))
        {

            if(*ptemp>='A'&&*ptemp<='Z')  
            {  
             *ptemp-='A';  
             *ptemp+=26-key;  
             *ptemp%=26;  
             *ptemp+='a';  
            }  


        }
        ptemp++;
    }

    e=w;

}

void Caesar (char *inputFile, char *outputFile, int key, int mode)
{
     ifstream input;
     ofstream output;
     char buf, buf1;  
     input.open(inputFile);  
     output.open(outputFile);  
     buf=input.get();
     while(!input.eof())  
     {  
        if(mode == 1){
            encryption(&buf, &buf1, key);
        }else{
            decryption(&buf1, &buf, key);
        }
        output << buf;
        buf=input.get();
     }
     input.close();  
     output.close();
}

int main(){

    int key, mode;
    key = chooseKey();
    cout << "1 or 0: ";
    cin >> mode;
    Caesar("test.txt","coded.txt",key,mode);
    system("pause");
}

以下是我的程序的一些详细信息。我的代码模板在我的帖子顶部。

参数w是开头的文本,par e是解密后的文本。如果我们在 w* 文本中添加 shift 键并得到 *e,则加密正在进行中。反向过程使解密功能,我有加密的文本(* e),我想获取解密的文本(* w),子跟踪我从chooseKey函数获取的密钥移位。在 Caesar 函数中,我使用一个包含一些数据的输入文件,我想在输出文件中提取加密或解密的文本。我已经实现了加密和解密函数,我的问题是如何在 Caesar 函数中使用它们。我没有得到任何理想的结果,我的程序正在崩溃。请提及我的错误。任何解决方案?

【问题讨论】:

  • 欢迎来到 Stack Overflow!感谢您发布您的代码,但请在您的问题中添加更多描述:您遇到什么问题,您期望的结果是什么,到目前为止what have you tried?通过question checklist 将帮助我们更好地回答您的问题。谢谢!
  • 我编辑了代码示例以至少编译。您也应该将参数设置为encryptionconst char*
  • 正如其他人所提到的,您应该包括您所面临的确切问题,以使其他人能够帮助您。任何编译错误、运行时错误……

标签: c++


【解决方案1】:

您将单个字符的地址传递给decryption

buf=input.get();
 // ...
        encryption(&buf, &buf1, key);

然后你把它当作它指向一个 null-terminated 字符串。

while(*ptemp){
    // ...
    ptemp++;
}

这不会很好地工作,因为ptemp 并没有首先指向一个以空字符结尾的字符串。当您执行ptemp++ 时,您就处于未定义行为领域。

除此之外,还有许多其他陷阱(例如,不要在.eof() 上循环)和潜在的改进。

编辑哦,还有作业

w = e;

e = w;

没有任何效果(您将指针值分配给本地函数参数;返回时,这些变量甚至不再存在)。

这是一个经过整理的片段,我期望会做你想做的事:Live on coliru

#include <iostream>
#include <fstream>
using namespace std;

int chooseKey() {
    cout << "Give a number from 1-26: ";
    int key_number;
    while((!(cin >> key_number)) || (key_number < 1 || key_number > 26)) {
        cout << "Your number have to be from 1-26 (" << key_number << "). Retry: ";
        cin.clear();
    }
    return key_number-1;
}

template <typename InIt, typename OutIt>
void encryption(InIt f, InIt l, OutIt out, int key) {
    for (InIt ptemp = f; ptemp != l; ++ptemp)
    {
        if(isalpha(*ptemp))
        {
            char base = islower(*ptemp)? 'a' : 'A';
            *out++ = base + (*ptemp - base + key) % 26;
        } else
            *out++ = *ptemp;
    }
}

void Caesar(const char *inputFile, const char *outputFile, int key, int mode) {
    ifstream input(inputFile);
    ofstream output(outputFile);

    istreambuf_iterator<char> init(input), end;
    ostreambuf_iterator<char> outit(output);

    encryption(init, end, outit, mode? key : 26-key);
}

int main() {
    int key, mode;
    key = chooseKey();
    cout << "1 or 0: ";
    cin >> mode;
    Caesar("test.cpp", "coded.txt", key, mode);
}

【讨论】:

  • 我试过你的代码,文本确实是加密的,但我有解密问题。我刚刚更改了 *out++ = base + (*ptemp - base + key) % 26; to *out++ = base + (*ptemp - base - key) % 26;但它没有解密为开始文本?我做错了什么?
  • @xaliap81 erm...我的代码已经解密了!请参阅mode? key : 26-key(这就是 Ceasar 代码的美妙之处:解密实际上是使用旋转密钥进行加密)。此外,这就是 mode 最初的用途
  • 确实有效。谢谢你。但是如果我想单独实现一个不同的解密函数我该怎么做呢?
  • 你也会这样做。 template&lt;...&gt; void decryption(InIt f, InIt l, OutIt out, int key) { encryption(f,l,out,26-key); } // done(记住:code duplication is bad
  • 这么简单,我只要调用解密块里面的加密函数,对吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多