0

ファイルを暗号化するプログラムがありますが、末尾に「.safe」という拡張子を追加しています。したがって、最終結果は「file.txt.safe」のようなものになります。

ファイルを復号化しようとすると、ユーザーはファイル名「file.txt.safe」をもう一度入力します。これはcharに保存されます。ここで、「。safe」を削除して、ファイルの名前を元の名前に変更します。

以下を試しましたが、何も起こらないようでエラーはありません。

Decrypt (myFile); //decrypts myFile

char * tmp = myFile;
char * newFile;
newFile = strstr (tmp,".safe");  //search tmp for ".safe"
strncpy (newFile,"",5);   //replace .safe with ""

rename (myFile, newFile);

明らかな何かが欠けていることは確かですが、このアプローチがうまくいかない場合は、簡単な方法を探しています。

追加するために編集: (K-balloに対するポスターの応答からモデレーターによってコピーされました)

みんな、ありがとう。私はstd::stringアプローチを採用し、これが機能することを発見しました:

Decrypt(myFile); 
string str = myFile; 
size_t pos = str.find(".safe"); 
str.replace(pos,5,""); 
rename(myFile, str.c_str());
4

2 に答える 2

4

やりたいことは、strncpy行を次のように変更するだけで機能します。

*newFile = '\0';

ファイル名に初期の.safeが含まれている場合( file.safest.txt.safeなど)、または部分文字列.safeがまったく含まれていない場合、これにはまだ問題があります。配列の最後から検索して、何かを見つけたことを確認する方がよいでしょう。

これはより良いアプローチのように思えます (ただし、C++ ではを使用する方がよいでしょうstd::string):

char* filename = ...;
size_t filename_length = strlen( filename );
int safe_ext_pos = filename_length - 5; // 5 == length of ".safe"
if( safe_ext_pos > 0 && strcmp( ".safe", filename + safe_ext_pos ) == 0 )
    filename[ safe_ext_pos ] = '\0';

これはstd::stringコードのバージョンです:

std::string filename = ...;
int safe_ext_pos = filename.length() - 5; // 5 == length of ".safe"
if( safe_ext_pos > 0 && filename.compare( safe_ext_pos, 5, ".safe" ) == 0 )
    filename.erase( safe_ext_pos );
于 2012-06-04T18:17:14.490 に答える
0

次の点に注意してください。

my.safe.file.txt.safe

「.safe」を検索して削除するか、最初のファイル名を切り捨てるのではなく、実際に文字列の最後にあることを確認する必要があります。

std::string myfile = ...
Decrypt(myFile);

const std::string extension_to_remove = ".safe";
if (decryption is successful &&
    myfile.size() >= extension_to_remove.size() &&
    myfile.substr(myfile.size()-5) == extension_to_remove)
{
  std::string newFile = myfile.substr(0, myfile.size()-5);
  rename(myFile, newFile);
}

ファイル名の拡張子についても注意してください。ソフトウェアがファイル名に特別な形式を使用してファイルの種類を識別することは、本当にひどい慣行です。人間が望む規則を簡単に使用できます。

したがって、ファイルを復号化するためのコードは、このタスクを実行するべきではありません。代わりに、復号化コードは、復号化するファイルと出力を含むファイルを取る必要があります。次に、暗号化されたファイルの名前から出力ファイル名を計算するためのコードは、ユーザーが出力ファイル名を通知するユーザー インターフェイスなど、別の場所に存在する必要があります。コードは「.safe」が存在する場合は削除し、変更された名前をデフォルトの出力ファイル名として提供し、ユーザーが確認できるようにします。

void perform_decryption(std::string const &encrypted, std::string const &decrypted) {
    Decrypt(encrypted);
    if (decryption is successful && encrypted!=decrypted)
        rename(encrypted, decrypted);
}

std::string default_decrypted_name(std::string const &filename) {
    const std::string extension_to_remove = ".safe";
    if (filename.size() >= extension_to_remove.size() &&
        filename.substr(filename.size()-extension_to_remove.size()) == extension_to_remove)
    {
      return filename.substr(0, filename.size()-extension_to_remove.size());
    }
    return filename + ".decrypted";
}

* ファイル名拡張子を使用しない理由は次のとおりです。

  • ファイル名の拡張子は一意ではなく、状況によっては、ファイルの種類を明確に識別できない競合が発生することがあります。(本来の目的すら果たせないだけで十分なはず…)
  • 整理するためのファイル名の使いやすさが低下します。「myfile.txt」の名前を「myfile.txt.old」に変更すると、テキスト ファイルとして表示されなくなります。
  • 本物の型のメタデータが隠されている場合、偽の型のメタデータが本物の型のメタデータと間違えられる可能性があるため、セキュリティ上の問題が発生します。
  • もっと...
于 2012-06-04T19:45:46.203 に答える