openssl — base64 декодирует c ++ неудачный конец строки байта

Я хотел бы декодировать строку большого файла в C ++.

Размер цепочки составляет: 1827500 знаков
и файл: 1370626 байт

Моя проблема в том, что функция декодирования не работает.
Декодированный файл отличается от исходного файла.

Ниже приведены два способа, которые я пробовал

Первый :

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

Во-вторых:

Код отсюда: Как base64 кодировать (декодировать) в C?

Некоторые концы строк отличаются:

Diff с WinMerge

Но не весь файл:

Левый визуализатор WinMerge diff

Ты можешь сказать мне, почему? и / или скажите мне другой способ кодирования файла для легкого переноса?

У меня есть это на входе: drive.google.com/file/d/0B1i4Ez8N86wFblJnaFF6YVNVTWs/view

И я хочу это в выходной: drive.google.com/file/d/0B1i4Ez8N86wFdl9OUE5UMFB3R28/view

(извините, я не могу поставить больше 2 ссылок)

PS: когда я декодирую с помощью «certutil -decode» в пакетном режиме, это работает без проблем.

Решено: проблема решена, проблема была написана. Исправлено с функцией записи ofstream

0

Решение

Ваш код для чтения данных в формате 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, но вы никогда ничего с этим не делаете. Затем вы копируете содержимое вашего чистого буфера в выходной буфер. Вы также можете покончить с вашим size указатель, и просто вернуть std::string вместо сырого char*,

Другая возможная проблема — линия

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

LIVE DEMO

Вы также, вероятно, захотите добавить обработку ошибок, чтобы очистить BIO случаи в случае ошибки (как в ответе, на который вы ссылались), но это не то, что приводит к неправильному результату.

1

Другие решения

Решено: проблема решена, проблема была написана. Исправлено с функцией записи ofstream

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector