简体   繁体   English

base64解码c ++失败行尾字节

[英]base64 decode c++ fail end of line byte

I would like to decode a string of a large file in c++. 我想在c ++中解码一个大文件的字符串。

The size of the chain is: 1827500 characters and the file is: 1370626 bytes 链的大小为:1827500个字符,文件为:1370626字节

My problem is that the decoding function does not work. 我的问题是解码功能不起作用。 The decoded file is different from the original file. 解码后的文件与原始文件不同。

Below are two ways I've tried 以下是我尝试过的两种方法

First : 首先:

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;
}

Second: 第二:

Code from here : How do I base64 encode (decode) in C? 来自这里的代码: 如何在C中对base64进行编码(解码)?

Some end of lines are different: 行尾有些不同:

与WinMerge差异

But not the entire file: 但不是整个文件:

WinMerge diff的左可视化器

Can you tell me why? 你能告诉我为什么吗? and / or tell me another way to encode a file for easy transfert ? 和/或告诉我另一种编码文件以便于传输的方式?

I have this in input : drive.google.com/file/d/0B1i4Ez8N86wFblJnaFF6YVNVTWs/view 我在输入中输入了以下内容:drive.google.com/file/d/0B1i4Ez8N86wFblJnaFF6YVNVTWs/view

And i want this in output : drive.google.com/file/d/0B1i4Ez8N86wFdl9OUE5UMFB3R28/view 我想在输出中使用它:drive.google.com/file/d/0B1i4Ez8N86wFdl9OUE5UMFB3R28/view

(sorry i can't put more than 2 links) (对不起,我不能超过2个链接)

PS: When i decode with "certutil -decode" in batch, it works without problems. PS:当我用“ certutil -decode”批量解码时,它可以正常工作。

SOLVED : Problem solved, the problem was fwrite . 已解决:问题已解决,问题已解决。 Fix with ofstream write function 使用ofstream写入功能修复

Your code to read the base64-ed data is pretty messed up: 您读取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;

You read your data into a string called result , but you never do anything with it. 您将数据读入名为result的字符串中,但从未对其执行任何操作。 Then you copy the contents of your scratch buffer into your output buffer. 然后,将暂存缓冲区的内容复制到输出缓冲区中。 You could also do away with your size pointer, and just return a std::string instead of a raw char* . 您也可以删除size指针,只返回std::string而不是raw char*

Another possible issue is the line 另一个可能的问题是生产线

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

If your input does contain newlines, then that line will cause problems. 如果您的输入中确实包含换行符,那么该行将引起问题。 If you want to work with input that may or may not contain newlines, you'll need to make that line conditional: 如果要使用可能包含换行符或不包含换行符的输入,则需要将该行设置为条件行:

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

All together, that would look something like this: 所有这些看起来像这样:

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();
}

LIVE DEMO 现场演示

You'll also probably want to add some error handling to clean up your BIO instances in case of error (like in the answer you linked to), but that isn't what's causing the wrong result. 您可能还想添加一些错误处理,以在发生错误的情况下清理您的BIO实例(例如您链接到的答案),但这并不是导致错误结果的原因。

SOLVED : Problem solved, the problem was fwrite . 已解决:问题已解决,问题已解决。 Fix with ofstream write function 使用ofstream写入功能修复

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM