1

C ++で大きなファイルの文字列をデコードしたいと思います。

チェーンのサイズ: 1827500 文字、ファイル: 1370626 バイト

私の問題は、デコード機能が機能しないことです。デコードされたファイルは元のファイルとは異なります。

以下は私が試した2つの方法です

初め :

char  *base64_decode(const std::string &input, long *size)
{
    BIO *p_bio_mem = nullptr;
    BIO *p_bio_b64 = nullptr;
    char *retrnvalue;

    p_bio_b64 = BIO_new(BIO_f_base64());
    if (!p_bio_b64) { throw std::runtime_error("BIO_new failed"); }
    BIO_set_flags(p_bio_b64, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines

    p_bio_mem = BIO_new_mem_buf((void*)input.c_str(), input.length());
    if (!p_bio_mem) { throw std::runtime_error("BIO_new failed"); }
    BIO_push(p_bio_b64, p_bio_mem);

    // read result from chain
    // read sequence (reverse to write): buf <<-- p_bio_b64 <<-- p_bio_mem
    std::vector<char> buf((input.size() * 3 / 4) + 1);
    std::string result;
    for (;;)
    {
        auto nread = BIO_read(p_bio_b64, buf.data(), buf.size());
        if (nread < 0) { return NULL; //fail}
        if (nread == 0) { break; } // eof
        result.append(buf.data(), nread);
    }

    BIO_free_all(p_bio_b64);
    *size = buf.size();
    retrnvalue = new char[*size];
    memcpy(retrnvalue, buf.data(), *size);

    return retrnvalue;
}

2番:

ここからのコード: C で base64 エンコード (デコード) するにはどうすればよいですか?

一部の行末が異なります。

WinMerge との差分

しかし、ファイル全体ではありません:

WinMerge diff の左のビジュアライザー

なぜか教えてくれますか?および/または簡単に転送できるようにファイルをエンコードする別の方法を教えてください。

入力にこれがあります:drive.google.com/file/d/0B1i4Ez8N86wFblJnaFF6YVNVTWs/view

そして、私はこれを出力したい: drive.google.com/file/d/0B1i4Ez8N86wFdl9OUE5UMFB3R28/view

(2つ以上のリンクを貼れなくてすみません)

PS: バッチで「certutil -decode」でデコードすると、問題なく動作します。

解決済み : 問題は解決しました。問題は fwrite でした。ofstream書き込み機能で修正

4

2 に答える 2

1

base64 で編集されたデータを読み取るためのコードはかなりめちゃくちゃです。

std::vector<char> buf((input.size() * 3 / 4) + 1);
std::string result;
for (;;)
{
    auto nread = BIO_read(p_bio_b64, buf.data(), buf.size());
    if (nread < 0) { return NULL; } //fail
    if (nread == 0) { break; } // eof
    result.append(buf.data(), nread);
}

BIO_free_all(p_bio_b64);
*size = buf.size();
retrnvalue = new char[*size];
memcpy(retrnvalue, buf.data(), *size);

return retrnvalue;

データを という文字列に読み込みますresultが、それに対して何もすることはありません。次に、スクラッチ バッファーの内容を出力バッファーにコピーします。また、ポインターを廃止して、 raw の代わりに a をsize返すこともできます。std::stringchar*

別の考えられる問題は、行です

BIO_set_flags(p_bio_b64, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines

入力に改行が含まれている場合、その行が問題を引き起こします。改行を含む場合と含まない場合がある入力を操作する場合は、その行を条件付きにする必要があります。

if (input.find('\n') == std::string::npos) {
    BIO_set_flags(p_bio_b64, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines
}

まとめると、次のようになります。

std::string base64_decode(const std::string &input)
{
    BIO *p_bio_mem = nullptr;
    BIO *p_bio_b64 = nullptr;

    p_bio_b64 = BIO_new(BIO_f_base64());
    if (!p_bio_b64) { throw std::runtime_error("BIO_new failed"); }
    if (input.find('\n') == std::string::npos) {
        BIO_set_flags(p_bio_b64, BIO_FLAGS_BASE64_NO_NL); //Don't require trailing newlines
    }

    p_bio_mem = BIO_new_mem_buf((void*)input.c_str(), input.length());
    if (!p_bio_mem) { throw std::runtime_error("BIO_new failed"); }
    BIO_push(p_bio_b64, p_bio_mem);

    std::stringstream result;
    std::vector<char> buf(1024);
    while (auto nread = BIO_read(p_bio_b64, buf.data(), buf.size()))
    {
        if (nread < 0) { throw std::runtime_error("OMGZ"); } //fail
        result.write(buf.data(), nread);
    }

    BIO_free_all(p_bio_b64);
    return result.str();
}

ライブデモ

また、エラーが発生した場合にインスタンスをクリーンアップするためにエラー処理を追加することもできますBIOが (リンク先の回答のように)、それが間違った結果の原因ではありません。

于 2016-08-27T00:26:36.633 に答える
0

解決済み : 問題は解決しました。問題は fwrite でした。ofstream書き込み機能で修正

于 2016-08-31T23:02:26.723 に答える