Расшифровывающий инструмент Shift (Cesar Cipher) - PullRequest
0 голосов
/ 09 марта 2012

Я создал Программу для расшифровки шифров сдвига (Cesar Cipher). Кажется, он берет Input и создает выходной файл, но он пуст. Я думаю, что что-то может быть не так с функцией расшифровки и попытался изменить несколько вещей безрезультатно. Я использую 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 голосов
/ 09 марта 2012

Я заметил несколько серьезных проблем.

1) Вы не зацикливаетесь при переключении.Таким образом, если shift = 20 и вы получаете символ 'y', когда вы делаете это:

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

asciiCode становится 'y' + 20 == 141, что находится за пределами стандартного 128-битного ascii.Вам нужно взять номер мода, я думаю, 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

даст вам знать, если ошибка в обработке файла.

0 голосов
/ 09 марта 2012

У вас есть пара логических ошибок. Я думаю, что ваши последние две функции должны быть больше похожи на:

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.

0 голосов
/ 09 марта 2012

Мне кажется, вы забыли ofstream::close ваш выходной файл.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...