base64使用openssl BIO块解码
问题描述:
我使用以下代码解码base64编码数据时遇到问题。我有大约3.5 MB的数据解码。它几乎没有问题,直到最后的东西丢失。base64使用openssl BIO块解码
以下代码读取100 kB源数据块,将其写入BIO_s_mem,然后多次读取1024字节的解码数据。当没有更多内容要读取时,另一个100 kB块将被检索并再次使用。它一直很好,直到收到最后一个块。它没有完整的100 kB(仅25685字节)。我把它写入BIO,获得18倍解码的1024字节,然后是另一个435,就是这样。但并非全部。大约100个字节的解码数据仍然没有被读取。
所有编码数据都被正确接收(将它们保存到文件中,并通过shell命令手动解码以提供完整的输出)。我应该如何从BIO中获得其余的?我想我应该以某种方式说这是一切。我尝试了多种方式,例如BIO_flush,一些标志,将新行添加到编码数据,但还没有成功。
BIO *bmem, *b64;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
BIO_push(b64, bmem);
vector<char> buf(1024);
while (!end) {
end = task->nextChunk(chunk, chunkSize); // this reads encoded data block
BIO_write(bmem, (void*)chunk, chunkSize);
cout << "Chunk size: " << chunkSize << endl;
if (end || chunkSize == 0) {
BIO_flush(bmem); // I tried multiple things
BIO_flush(b64); // flush here and there, nothing helped
BIO_set_close(bmem, BIO_CLOSE); // and other things... ;-)
}
string result;
int nread;
while ((nread = BIO_read(b64, buf.data(), buf.size())) > 0) {
cout << "Decoded bytes read: " << nread << endl;
result.append(buf.data(), nread);
}
ret->appendRaw(result.c_str(), result.size()); // store result somehow
}
最后输出序列:
Chunk size: 25685
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 1024
Decoded bytes read: 435
Chunk size: 0
所以再次:解码输出是二进制文件。它被正确编码,正确发送到我的代码,但没有解码,最后大约有100个字节丢失。 谢谢你的提示。
答
诀窍是在最后的序列BIO_READ之前加入以下两行:
BIO_write(bmem, "\n", 1);
BIO_set_mem_eof_return(bmem, BIO_NOCLOSE);
I *认为*'(NREAD = BIO_READ(B64,buf.data(),buf.size()))> 0'可能不完全正确。我认为在生物上进行的测试是'do {len = BIO_read(b64,...); } while(len> 0 || BIO_should_retry(b64));'但是这是一个套接字生物;我不确定文件或内存生物的差异。 – jww
谢谢你的提示。我已经尝试过这一点。当所有块写入我的BIO_s_mem时,从b64读取给出-1和BIO_should_retry(b64)保持为真,所以它永远不会结束。这就是为什么我认为我需要说“这一切”,最后一部分将被解码,返回,循环可以完成。 – Martin