首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >移位解密工具(塞萨尔密码)

移位解密工具(塞萨尔密码)
EN

Stack Overflow用户
提问于 2012-03-09 10:42:24
回答 3查看 1.9K关注 0票数 0

我已经建立了一个程序来破译移位密码(塞萨尔密码)。它似乎接受输入并生成输出文件,但它是空的。我在想,可能是解密功能出了问题,我尝试过多次更改,但都无济于事。我使用放血C++进行编译,使用windows作为操作系统。

谢谢

kd7vdb

代码语言:javascript
运行
复制
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>

using namespace std;
const int ARRAYSIZE = 128;

void characterCount(char ch, int list[]);
void calcShift( int& shift, int list[]);
void writeOutput(ifstream &in, ofstream &out, int shift);

int main()
{
    int asciiCode = 0,
        shift = 0;
    string filename;
    char ch;
    ifstream infile;
    ofstream outfile;

    //input file

    cout << "Input file name: ";
    getline(cin, filename);

    infile.open(filename.c_str());

        if (!infile.is_open()) { 

            cout << "Unable to open file or it doesn't exist." << endl;

            return 1;

        }

    //output file

    cout << "Output file name: ";
    getline(cin, filename);



    outfile.open(filename.c_str());

    int list[ARRAYSIZE] = {0}; 

        while (infile.peek() != EOF) 
        {
            infile.get(ch);
            characterCount(ch, list); 
        }



    infile.clear();
    infile.seekg(0);

    calcShift (shift, list); //Calculate the shift based on the <strong class="highlight">most</strong> characters counted
    writeOutput(infile, outfile, shift); //Decypher and write to the other document

    return 0;
}

void characterCount(char ch, int list[])
{
        if (ch >= 'A' && ch <= 'z') //If the character is in the alphabet...
        {
            int asciiCode = 0;

            asciiCode = static_cast<int>(ch); //Change it to the ASCII number
            list[asciiCode]++; //And note it on the array
        }
}

void calcShift( int& shift, int list[])
{
    int maxIndex = 0, //Asuming that list[0] is the largest
        largest = 0;

        for (int i = 1; i < ARRAYSIZE; i++)
        {
            if (list[maxIndex] < list[i])
                    maxIndex = i; //If this is true, change the largest index
        }

    largest = list[maxIndex]; //When the maxIndex is found, then that has the largest number.

        if (largest >= 65 && largest <= 90) //Calculate shift with <strong class="highlight">E</strong> (for upper-case letters)
            shift = largest - 69;

        if (largest >= 97 && largest <= 122) //For lower-case letters (<strong class="highlight">e</strong>)
            shift = largest - 101;
}

void writeOutput(ifstream &infile, ofstream &outfile, int shift)
{
    char ch;
    int asciiCode = 0;

        while (infile.peek() != EOF) { //Until it is the end of the file...

            infile.get(ch); //Get the next character

                if (ch >= 'A' && ch <= 'z') //If the character is in the alphabet...
                {
                    asciiCode = static_cast<int>(ch); //Change it to the ASCII number
                    asciiCode += shift; //Do the shift
                    ch = static_cast<char>(asciiCode); //Change it to the shifted letter
                }

            outfile << ch; //Print to the outfile
        }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-09 12:24:49

你有几个逻辑错误。我认为你最后两个函数应该更像这样:

代码语言:javascript
运行
复制
void calcShift( int& shift, int list[])
{
    int maxIndex = 0; //Asuming that list[0] is the largest

    for (int i = 1; i < ARRAYSIZE; i++)
    {
        if (list[maxIndex] < list[i])
                maxIndex = i; //If this is true, change the largest index
    }

    if (maxIndex >= 'A' && maxIndex <= 'Z') //Calculate shift with <strong class="highlight">E</strong> (for upper-case letters)
        shift = 'E' - maxIndex;

    if (maxIndex >= 'a' && maxIndex <= 'z') //For lower-case letters (<strong class="highlight">e</strong>)
        shift = 'e' - maxIndex;
}

void writeOutput(ifstream &infile, ofstream &outfile, int shift)
{
    char ch;

    while (infile.peek() != EOF) { //Until it is the end of the file...

        infile.get(ch); //Get the next character

            if (ch >= 'A' && ch <= 'Z') //If the character is in the alphabet...
            {
                ch = 'A' + (((ch - 'A') + shift + 26) % 26);
            }
            if (ch >= 'a' && ch <= 'z') //If the character is in the alphabet...
            {
                ch = 'a' + (((ch - 'a') + shift + 26) % 26);
            }

        outfile << ch; //Print to the outfile
    }
}

总而言之,在calcShift中你不需要largest,你需要从'E''e'中减去maxIndex来计算移位,并且你在writeOutput中计算被替换的字符的误差很大。

我不确定为什么你会得到一个空的输出文件,但这对我使用MSVC是有效的。

票数 0
EN

Stack Overflow用户

发布于 2012-03-09 11:08:30

在我看来,你忘记了ofstream::close你的输出文件。

http://www.cplusplus.com/reference/iostream/ofstream/close/

票数 0
EN

Stack Overflow用户

发布于 2012-03-09 11:11:28

我注意到了一些严重的问题。

1)换档时,你不能绕圈子。因此,如果shift = 20,并且你得到字符'y',当你这样做的时候:

代码语言:javascript
运行
复制
asciiCode = static_cast<int>(ch); //Change it to the ASCII number
asciiCode += shift; //Do the shift
ch = static_cast<char>(asciiCode);

asciiCode变为'y‘+20ASCII 141,这超出了标准128位==的末尾。我想你需要乘坐mod的号码,128。所以:

代码语言:javascript
运行
复制
asciiCode = static_cast<int>(ch); //Change it to the ASCII number
asciiCode += shift; //Do the shift
asciiCode %= 128; // Wrap around
ch = static_cast<char>(asciiCode);

2)但这仍然不能解决为什么您只移动字母字符,而在结果中将这些字母转换为非字母字符。

为什么要以128而不是52的数组来计算它们呢?还是只有26岁?

更重要的是,为什么要在代码中生成移位值?您需要知道该值以便稍后解码...

简而言之,我建议你这样做:

  • 在应用移位时将字符转换为数字0-51,而不是0-127 (或0-25)
  • ,将其与0-51值相加,然后取该% 52以获得手动输入移位值的新

这就是Ceasar Cypher通常的工作方式。

3)关于打印问题,您试过调试了吗?

我不能谈论放血C++,但即使只是添加一条cout语句也会非常有帮助。例如:

代码语言:javascript
运行
复制
std::cout << ch; //Print to cout for debugging
outfile << ch; //Print to the outfile

如果错误发生在输出文件处理中,我会让您知道。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9628239

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档