2012-03-09 24 views
0

シフト暗号を解読するプログラム(Cesar Cipher)を構築しました。それは入力を受け取り、出力ファイルを作るようですが、それは空です。私は何かが解読関数に間違っているかもしれないと考えていて、何も役に立たないものを変更しようとしました。コンパイルにはBloodshed C++を使用し、OSにはWindowsを使用します。シフト解読ツール(cesar暗号)

おかげ

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

答えて

0

論理的なエラーが2つあります。要約すると、あなたはcalcShiftlargestを必要としない、あなたがシフトを計算する'E'または'e'からmaxIndexを引く必要があり、かつ置換のあなたの計算

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

:私はあなたの最後の二つの機能をもっとすべきだと思いますwriteOutputの文字はかなり遠いです。

なぜ私は空の出力ファイルを取得していたのか分かりませんが、これはMSVCを使用して私の作品です。

+0

私はofstream :: closeが欠けていましたが、出力はまだ処理されていません。 編集:今正しく処理されていません。 – kd7vdb

+0

これは完全に働いています、ありがとうございました。 KD7VDB – kd7vdb

0

私が気づいたいくつかの深刻な問題があります。

1)移動中に折り返していません。だから、あなたがこれを行う際にシフト= 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'、標準の128ビットASCIIの終わりを過ぎている+ 20 == 141、になります。

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、私は推測する、番号のMODを取る必要があります結果。

なぜ、52ではなく128のサイズの配列でカウントしていますか?またはちょうど26?

さらに、なぜコード内にシフト値を生成していますか?

  • むしろ0-127(または0よりも、数字0から51までの文字を翻訳:あなたは私はあなたがこのようにそれを行うreccommend、

    要するに

    ...後で復号化するために、その値を知っておく必要があります-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

私は実際にsd :: cout << chを使いました。出力は未処理のようです。また、出力ファイルへの書き込みも行いません。 – kd7vdb

関連する問題