移位解密工具(cesar cipher)

时间:2012-03-09 02:42:24

标签: c++ encryption

我已经构建了一个程序来解密移位密码(Cesar Cipher)。它似乎采取输入并生成一个输出文件,但它是空的。我认为解密功能可能有问题,并尝试改变多项内容无济于事。我使用Bloodshed C ++编译和操作系统的Windows。

由于

kd7vdb

#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
        }
}

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

1)你在换班时不会四处走动。因此,如果shift = 20并且你得到了字符&#39; y&#39;,当你这样做时:

asciiCode = static_cast<int>(ch); //Change it to the ASCII number
asciiCode += shift; //Do the shift
ch = static_cast<char>(asciiCode);

asciiCode成为&#39; y&#39; + 20 == 141,这是标准128位ascii的结尾。我需要取数字mod,我猜,128。所以:

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)关于打印问题,您是否尝试过调试?

我不能谈论Bloodshed C ++,但即使只是添加一个cout语句也会非常有用。例如:

std::cout << ch; //Print to cout for debugging
outfile << ch; //Print to the outfile

会告诉您错误是否在outfile处理中。

答案 2 :(得分:0)

您有几个逻辑错误。我认为你的最后两个功能应该更像:

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
    }
}

总结一下,largest中不需要calcShift,您需要从maxIndex'E'中减去'e'来计算转移,并且你在writeOutput中对替换字符的计算相当远。

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