2

私はこのコードを調べて、デスクトップ上の cesar 暗号コードを解読するファイルを読み取っていましたが、このプログラムでシフトがどのように計算されるかを理解しようとして立ち往生しています。

私が知る限り、Max e's は最も頻度の高いシフトされた文字です。e は英語で最も一般的な文字であるため、プログラムは暗号で最も頻度の高い文字を英語の 'e' に設定しようとしています。これは良いことですが、e が最も頻繁に使用される文字ではないフレーズが多くあり、それが顔に出てきます。

したがって、最も頻繁に使用される暗号文字がプレーンテキストの e であると推測するようにプログラムに指示するにはどうすればよいでしょうか。見つけるまで?

友人がその部分を手伝ってくれましたが、英語が下手なので、彼が私に説明するのは難しい. 誰か詳しく教えてください。助けていただければ幸いです。どう考えているか教えてください:

#include <iostream>
#include <string>
#include <cctype> // isalpha, islower, isupper, functions
#include <fstream>
using namespace std;

string caesarShift(string text, int shift);
int main()
{
    int maxEs = 0;       // # of e's in maxString
    int currentEs = 0;    // # of e'sin currentString
    string maxString;       // decrypted caesar shift with most e's
    string currentString;    //decrypted caesar shift

    string cipher;       // Stores cipher text
    char ch;    // Stores currentcharacter for reading
    ifstream fin("/Users/jasonrodriguez/Desktop/encrypted.txt");   //opens "encrypted.txt" file
    while( fin.get(ch) )    // readseach char into the cipher till EOF
    {
        cipher += ch;
    }
    fin.close();    // be safe andclose file

    for(int i=0; i < 26; i++)
    {
        currentEs =0;    // Reset counter
        currentString =caesarShift(cipher, i);    // get shifted text
        for(unsigned int x=0; x <currentString.size(); x++) // check each character of stringarray
        {
            if(currentString[x] == 'e' || currentString[x] == 'E') // check fore's
            {
                currentEs++;    // increment Ecounter
            }
        }
        if(currentEs > maxEs) //if currentEs is greater than maxEs, replace max with current
        {
            maxEs =currentEs;
            maxString= currentString;
        }
    }
    cout << maxString << endl;
    return 0;
}

/**
 string caesarShift(string text, int shift)
 Decrypts Caesar Shift using text and shift
 */
string caesarShift(string text, int shift)
{
    shift = shift % 26;    // Morethan 26 is redundant and unneeded
    char ch = 0; // holds current character
    char chs = 0;    // holds shiftedcharacter
    for(unsigned int i=0; i < text.size();i++)
    {
        ch = text[i];
        if( isalpha(ch) )
        {
            chs = ch -shift; // reverse shifting
            if( (islower(ch) && chs < 'a' )  // If is lowercase andshifted value is lower than 'a'
               ||
               ( isupper(ch) && chs < 'A' ) ) // Ifis uppercase and shifted value is lower than 'A'
            {
                chs += 26;    // Add 26(number ofletters) to get back to the correct place in alphabet
            }
            text[i] =chs;    // Set character to shifted character
        }
    }
    return text;
}

質問:

  1. 私が知る限り、Max e's は最も頻度の高いシフトされた文字です。e は英語で最も一般的な文字であるため、プログラムは暗号で最も頻度の高い文字を英語の 'e' に設定しようとしています。これは良いことですが、e が最も頻繁に使用される文字ではないフレーズが多くあり、それが顔に出てきます。したがって、最も頻繁に使用される暗号文字がプレーンテキストの e であると推測するようにプログラムに指示するにはどうすればよいでしょうか。見つけるまで?

  2. 文字をシフト量だけシフトすると、文字が範囲外になる場合とそうでない場合があると思います。'a' + 3 は 'd' です。'x' + 3 は '{' です。したがって、文字が 'z' を超えている場合は 26 を取り除き、'a' の下にある場合は 26 を追加します。使用可能な関数になる可能性があります。ただし、シフトがプログラムでどのように計算され、ファイルに適用されるかを教えてください。それは私を完全に困惑させます:(

4

1 に答える 1

0

シフトの計算:

まず、文字 'A' から 'Z' (大文字のみを想定) を 0 から 25 の整数にマップする必要があります。C++ では、減算を使用してこれを簡単に行うことができます。

n = c - 'A';

これで、モジュラス演算でシフトを実行できます。

n = (n + shift) % 26;

最後に文字に戻します:

p = n + 'A';

(これらの例で使用される変数には、適切な宣言が必要になることに注意してください。私が使用する 1 文字の変数名よりも意味のある名前を使用することをお勧めします。)

于 2013-03-12T22:57:32.103 に答える