2012-05-09 16 views
7

que tratar de utilizar el codificador base64 impulso, me encontré con un ejemplo pero me dio y la excepcióncodificación Base64 excepción utilizando impulso tiro

typedef 
transform_width< binary_from_base64<std::string::const_iterator>, 8, 6 > it_binary_t 

un utilicé

std::string b64E(it_binary_t(Encrip.begin()), it_binary_t(Encrip.end())); 

lo entiendo

Excepción no controlada en 0x75b1b9bc en agentid_coder.exe: excepción de Microsoft C++ : boost :: archive :: iterators :: dataflow_exception en la memoria ubicación 0x0046ed94 ..

me encontré con esta solución, pero me sale el mismo resultado

string dec( 
     it_binary_t(Encrip.begin()), 
     it_binary_t(Encrip.begin() + Encrip.length() - 1) 
     ); 

estoy usando MSVS2008 e impulsar 1.38

+0

Funciones de codificación de Base64 con Boost C++ Library: http://stackoverflow.com/questions/34680998/attempt-to-decode-a-value-not-in-base64-char-set – ap6491

Respuesta

28

Por desgracia, la combinación de los dos iterator_adaptors y binary_from_base64transform_width no es un codificador/decodificador base64 completo. Base64 representa grupos de 24 bits (3 bytes) como 4 caracteres, cada uno de los cuales codifica 6 bits. Si los datos de entrada no son un múltiplo entero de dichos grupos de 3 bytes, tiene que rellenarse con uno o dos bytes cero. Para indicar cuántos bytes de relleno se agregaron, se añaden uno o dos caracteres = a la cadena codificada.

transform_width, que es responsable de la conversión de 8 bits de entero a 6 bits no aplica este relleno automáticamente, lo debe hacer el usuario. Un ejemplo simple:

#include <boost/archive/iterators/base64_from_binary.hpp> 
#include <boost/archive/iterators/binary_from_base64.hpp> 
#include <boost/archive/iterators/transform_width.hpp> 
#include <boost/archive/iterators/insert_linebreaks.hpp> 
#include <boost/archive/iterators/remove_whitespace.hpp> 
#include <iostream> 
#include <string> 

using namespace boost::archive::iterators; 
using namespace std; 

int main(int argc, char **argv) { 
    typedef transform_width< binary_from_base64<remove_whitespace<string::const_iterator> >, 8, 6 > it_binary_t; 
    typedef insert_linebreaks<base64_from_binary<transform_width<string::const_iterator,6,8> >, 72 > it_base64_t; 
    string s; 
    getline(cin, s, '\n'); 
    cout << "Your string is: '"<<s<<"'"<<endl; 

    // Encode 
    unsigned int writePaddChars = (3-s.length()%3)%3; 
    string base64(it_base64_t(s.begin()),it_base64_t(s.end())); 
    base64.append(writePaddChars,'='); 

    cout << "Base64 representation: " << base64 << endl; 

    // Decode 
    unsigned int paddChars = count(base64.begin(), base64.end(), '='); 
    std::replace(base64.begin(),base64.end(),'=','A'); // replace '=' by base64 encoding of '\0' 
    string result(it_binary_t(base64.begin()), it_binary_t(base64.end())); // decode 
    result.erase(result.end()-paddChars,result.end()); // erase padding '\0' characters 
    cout << "Decoded: " << result << endl; 
    return 0; 
} 

Nota que añadí los insert_linebreaks y remove_whitespace iteradores, de modo que la salida base64 está muy bien formateado y de entrada base64 con saltos de línea puede ser decodificado. Sin embargo, estos son opcionales.

Ejecutar con diferentes cadenas de entrada que requieren diferentes padding:

$ ./base64example 
Hello World! 
Your string is: 'Hello World!' 
Base64 representation: SGVsbG8gV29ybGQh 
Decoded: Hello World! 
$ ./base64example 
Hello World!! 
Your string is: 'Hello World!!' 
Base64 representation: SGVsbG8gV29ybGQhIQ== 
Decoded: Hello World!! 
$ ./base64example 
Hello World!!! 
Your string is: 'Hello World!!!' 
Base64 representation: SGVsbG8gV29ybGQhISE= 
Decoded: Hello World!!! 

Usted puede comprobar las cuerdas base64 con este online-encoder/decoder.

+2

Bien hecho para agregar una codificación completa/Descodificar la implementación! La falta de relleno también me sorprendió. – DanDan

+0

¿Puede explicar por qué necesita segundo% 3 in (3-s.length()% 3)% 3 – NoSenseEtAl

+0

Necesitamos un resultado en {0,1,2}. Sin el segundo% 3 obtenemos un resultado en {1,2,3}. El último% 3 asigna el resultado 3 a 0 y deja solo 1 y 2. Otra posibilidad sería algo como s.length()% 3? 3-s.length()% 3: 0 – PiQuer

Cuestiones relacionadas