2

暗号化と復号化のために、c++ でコードを作成しました。最初のコードは vector で出力を作成し、fwrite を使用してファイルに書き込みます。2 番目のコードは、fread を使用して最初のコードからその出力を読み取ります。ここに私のコードのスニペットがあります:

1番目のコード:

.....
string a;
vector<long long int> c;

cout << "message to be encrypted = ";
cin >> a;   
cout << endl;

cout << "Encrypted message : ";
for (i=0;i<a.size();i++) 
{
    x=(int)a.at(i);
    cout << x << " ";
    c.push_back(powerMod(x,e,n));
}

for (i=0;i<c.size();i++) 
{
    //cout << char(c.at(i));
}
cout << endl;

//Write ciphertext c to a file
FILE * pWrite;
pWrite = fopen ("ciphertext", "w");
fwrite (&c , sizeof(c), 1, pWrite);
fclose (pWrite);

出力は次のとおりです。

message to be encrypted = test
Encrypted message : 116 101 115 116 

そして、2番目のコード:

....
//Read Ciphertext from ciphertext
FILE * pRead2;
pRead2 = fopen ("ciphertext", "r");
fread (&c , sizeof(c), 1, pRead2);
//cout << "ciphertext is " << c << endl;

// Decryption
cout << "Decrypted message : ";
for (i=0;i<c.size();i++) 
{
    cout << powerMod(c.at(i),d,n) << " " ;
}
cout << endl;

しかし、それは戻ります:

Segmentation Fault(Core Dumped)

fwrite または fread のどこに問題があるのか​​ わからないので、助けていただければ幸いです。しかし、問題は暗号文 (ベクトル) を読み取ろうとする 2 番目にあると思います。その行を消去すると、プログラムは完全に実行されますが、メッセージは復号化されません。

ありがとう。

4

1 に答える 1

6

これは、実際のベクター データではなく、ベクター オブジェクト インスタンスへのポインターを書き込むためです。使用する

fwrite (&c[0], sizeof(vector<long long int>::value_type), c.size(), pWrite);

また、ベクトル内のアイテムの数ではなく、ベクトル オブジェクト インスタンスsizeof(c)のサイズを返すことも忘れないでください。

ベクトルを読み取るときにも同様の問題があります。ループ内で 1 つずつ実行する必要があり、項目を再度ベクターにプッシュします。


C++ では、 C++ I/O ストリーム ライブラリといくつかの適切な標準アルゴリズムの使用方法とiteratorsの使用方法を習得すれば、これを行うためのより簡単な方法があります。

ベクトルをファイルに書き込むには:

std::ofstream os{"ciphertext", std::ios::out};

std::copy(std::begin(c), std::end(c),
          std::ostream_iterator<long long int>(os));

ファイルから読み取るには、次のようにします。

std::ifstream is{"ciphertext", std::ios::in};

std::copy(std::istream_iterator<long long int>(is),
          std::istream_iterator<long long int>(),
          std::back_inserter(c));

実際には、ファイルからベクターに読み取るさらに簡単な方法があります。

std::ifstream is{"ciphertext", std::ios::in};

std::vector<long long int> c(std::istream_iterator<long long int>(is),
                             std::istream_iterator<long long int>());

これは、 2 つの反復子を引数として受け取るstd::vectorコンストラクターに依存しています。


テキスト ファイルではなくバイナリ ファイルを使用したい場合は、残念ながら手動でループしてデータを読み書きする必要がありstd::copyます。

データを書き込むには、次のようにします。

std::ofstream os{"ciphertext", std::ios::out | std::ios::binary};

for (const auto& value : c)
    os.write(reinterpret_cast<const char*>(&value), sizeof(value));

そして、このようにそれを読んでください:

std::ifstream is{"ciphertext", std::ios::in | std::ios::binary};

long long int value:
while (is.read(reinterpret_cast<char*>(&value), sizeof(value)))
    c.push_back(value);

C++11の範囲ベースのforループ(上記の記述例で使用) がない場合は、通常の従来の反復forループを使用します。

std::vector<long long int>::const_iterator i;
for (i = c.begin(); i != c.end(); ++i)
    os.write(reinterpret_cast<const char*>(&(*i)), sizeof(*i));
于 2013-08-02T10:53:32.600 に答える