2014-12-17 35 views
5

Ho bisogno di una semplice compressione e decompressione di una stringa std :: in C++. Ho guardato questo site e il codice è per Array di caratteri. Quello che voglio implementare sono le due funzioni:Compressione e decompressione stringa semplice Zlib 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; 

avevo provato la compressione spinta come:

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

ma il codice a volte dà caratteri Null in stringa cioè \ u0000. Come gestisco se i dati compressi contengono questi caratteri nulli. Il tipo di ritorno stringa è corretto? Come posso implementare la funzione string_compress e string_decompress utilizzando zlib?

+4

dati compressa è solo dati binari. Non è una stringa sensata e leggibile (nel senso umano). Quindi non sorprende che si vedano dati binari "strani" nella stringa compressa. Dopotutto, esattamente quello che è. – Cornstalks

+0

Perché ti importa se nella stringa compressa ci sono caratteri null? – Galik

+0

Poiché il messaggio compresso viene inviato al server come stringa Json. Ma il server non può ricevere il messaggio completo una volta che vede il carattere null. – Pant

risposta

5

Si può fare come suggerito @LawfulEvil. Ecco il frammento di codice che funziona :)

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; 

Utilizzando this come la biblioteca base64 codifica/decodifica

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

Grazie Zangetsu. Proverò questo codice e informerò se funziona. – Pant

+2

Dovresti davvero elencare la sezione di inclusione del tuo codice per completezza. – Kahless

1

La compressione fa uso di tutti i valori disponibili per ogni byte, quindi apparirà come caratteri "garbage" o "bizzarri" quando si tenta di visualizzare come ascii. È previsto. Avrai bisogno di codificare i dati per la trasmissione/json packing per evitare valori nulli. Suggerisco la base 64. Il codice per farlo è disponibile al link sottostante (che non ho scritto quindi non copierò qui).

  1. http://www.adp-gmbh.ch/cpp/common/base64.html
  2. Binary data JSONCPP