Простое сжатие и распаковка строк Zlib C++
Мне нужно простое сжатие и распаковка std::string в C++. Я посмотрел на этом сайте, и код для символьного массива. Я хочу реализовать две функции:
std::string original = "This is to be compressed!!!!";
std::string compressed = string_compress(original);
std::cout << compressed << std::endl;
std::string decompressed = string_decompress(compressed);
std::cout << decompressed << std::endl;
Я пробовал компрессию буста как:
std::string CompressData(const std::string &data)
{
std::stringstream compressed;
std::stringstream decompressed;
decompressed << data;
boost::iostreams::filtering_streambuf<boost::iostreams::input> out;
out.push(boost::iostreams::zlib_compressor());
out.push(decompressed);
boost::iostreams::copy(out, compressed);
return compressed.str();
}
std::string DecompressData(const std::string &data)
{
std::stringstream compressed;
std::stringstream decompressed;
compressed << data;
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::zlib_decompressor());
in.push(compressed);
boost::iostreams::copy(in, decompressed);
return decompressed.str();
}
но код иногда дает нулевые символы в строке, то есть \ u0000. Как мне справиться, если сжатые данные содержат эти нулевые символы. Верна ли строка возвращаемого типа? Как я могу реализовать функции string_compress и string_decompress, используя zlib?
2 ответа
Вы можете сделать как предложено @LawfulEvil. Вот фрагмент кода, который работает:)
std::string original = "This is to be compressed!!!!";
std::string compressed_encoded = string_compress_encode(original);
std::cout << compressed_encoded << std::endl;
std::string decompressed_decoded = string_decompress_decode(compressed_encoded);
std::cout << decompressed_decoded << std::endl;
Использование этого в качестве библиотеки кодирования / декодирования base64
std::string string_compress_encode(const std::string &data)
{
std::stringstream compressed;
std::stringstream original;
original << data;
boost::iostreams::filtering_streambuf<boost::iostreams::input> out;
out.push(boost::iostreams::zlib_compressor());
out.push(original);
boost::iostreams::copy(out, compressed);
/**need to encode here **/
std::string compressed_encoded = base64_encode(reinterpret_cast<const unsigned char*>(compressed.c_str()), compressed.length());
return compressed_encoded.str();
}
std::string string_decompress_decode(const std::string &data)
{
std::stringstream compressed_encoded;
std::stringstream decompressed;
compressed_encoded << data;
/** first decode then decompress **/
std::string compressed = base64_decode(compressed_encoded);
boost::iostreams::filtering_streambuf<boost::iostreams::input> in;
in.push(boost::iostreams::zlib_decompressor());
in.push(compressed);
boost::iostreams::copy(in, decompressed);
return decompressed;
}
Сжатие использует все значения, доступные для каждого байта, поэтому оно будет отображаться как "мусор" или "странные" символы при попытке просмотра как ascii. Это ожидается. Вам нужно будет закодировать данные для передачи / упаковки JSON, чтобы избежать нулевых значений. Я предлагаю основание 64. Код для этого доступен по ссылке ниже (которую я не написал, поэтому я не буду копировать здесь).