0

Shit Cipher に取り組んでいて、特定のテキストを解読しています。さて、プログラムの仕組みは次のとおりです。

  1. テキストファイルから文字を取得します
  2. 各文字をアルファベットの 9 桁下にシフトします。

今、私はこれを行いましたが、文字を常に9桁シフトできるとは限らないことを知っているので、プログラムは文字がアルファベット文字配列のどこにあるかを調べ、それが可能であれば9を追加します.それができない場合は、単に 9 を減らします (差を見つけます)。しかし、それは機能しておらず、どこが間違っているのかわかりません。

コードは次のとおりです。

#include <iostream>
#include <fstream> 
using namespace std;

string inputFile = "";
#define MAX_FILE_SIZE 10000
const char alphabet[26] =   {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
const char alphabetUpper[26] =   
{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

const int sizeAlpha = sizeof(alphabet)/sizeof(alphabet[0]);
void Data(char* theData)
{
ifstream txtFile(inputFile.c_str());
if(!txtFile.is_open())
{
    cerr << "Cannot open text file";
}
txtFile.read(theData, 520);
}

int main(int argc, char *argv[]) {

char getData[MAX_FILE_SIZE];

Data(getData);

char decrypted[520];

int algorthm;

for(unsigned i=0; (i < 520); i++)
{
    for(unsigned j=0; (j < 26); j++)
    {
        if(getData[i] == alphabet[j] || alphabetUpper[j])
        {
            algorthm = j + 9; // we move 9 places.

            if(sizeAlpha < algorthm)
            {
                decrypted[i] = alphabet[algorthm];

            }else if(algorthm > sizeAlpha || algorthm == sizeAlpha) 
            {
                algorthm = sizeAlpha - j;

                decrypted[i] = alphabet[algorthm];
            }
        }
    }
}

for(unsigned i=0; (i < 520); i++)
{
    cout << decrypted[i]; 
}
}

私が間違っている場所を知っている人はいますか、それとも同様の解決策を提供できますか?

4

2 に答える 2

3

モジュロを行う必要があります:

algorthm = (j + 9) % 26;

オーバーフローを処理するために 9 を削除すると、他の文字との衝突が発生し、最初の 9 桁は使用されません。

[編集]ただ指摘するために...

if ステートメントにも問題があります。

if(getData[i] == alphabet[j] || alphabetUpper[j])

これはあなたが思っているようには機能しません。もしそうなら、後で大文字と小文字を区別しないため、アルゴリズムはとにかく機能しません。コードを複製するか、正しい配列へのポインターを設定する必要があります。しかし、それは長い道のりです。

テストを行うためにアルファベット文字の配列を検索する必要はありません。賢明な文字エンコーディング (そして、ASCII が最も一般的であると言えます) は、アルファベット文字を順番に保持します。そう:

const int shiftAmt = 9;
char c = getData[i];

if( c >= 'A' && c <= 'Z' )
    c = 'A' + ((c - 'A' + shiftAmt) % 26);
else if( c >= 'a' && c <= 'z' )
    c = 'a' + ((c - 'a' + shiftAmt) % 26);

decrypted[i] = c;

これにより、アルファベット以外の文字も保持されることに注意してください。ただし、コードはそれらを忘れて、「復号化された」配列のその位置を初期化せずに残しました。

于 2012-08-24T00:08:55.680 に答える
2

できる場合は9を足すだけで、できない場合は9を減らすだけです。

2 つの異なる値を同じ値にマップするため、元に戻すことはできません。

代わりに、ラップアラウンドする必要があります:

unsigned char shiftChar(unsigned char const plain, signed char const by) {
  unsigned char const caseBit = plain & ('a' ^ 'A');
  unsigned char offset = (plain ^ caseBit) - ('a' & 'A');
  offset += ('z' - 'a' + 1) + by; // there's your "shift"
  offset %= ('z' - 'a' + 1);
  return caseBit | (offset + ('a' & 'A'));
}
于 2012-08-24T00:17:14.213 に答える