2012-05-09 3 views
7

Je tente d'utiliser boost encodeur base64, je trouve un exemple mais je me suis et exceptionencode base64 en utilisant exception throw boost

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

un I utilisé

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

Je l'obtiens

Exception non gérée à 0x75b1b9bc dans agentid_coder.exe: Microsoft C++ exception: boost :: archive :: iterators :: dataflow_exception à la mémoire emplacement 0x0046ed94 ..

J'ai trouvé cette solution de contournement, mais je reçois le même résultat

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

J'utilise MSVS2008 et stimuler 1,38

+0

Fonctions de codage Base64 utilisant la bibliothèque Boost C++: http://stackoverflow.com/questions/34680998/attempt-to-decode-a-value-not-in-base64-char-set – ap6491

Répondre

28

Malheureusement, la combinaison des deux iterator_adaptorsbinary_from_base64 et transform_width n'est pas un codeur/décodeur base64 complet. Base64 représente des groupes de 24 bits (3 octets) sous la forme de 4 caractères codant chacun 6 bits. Si les données d'entrée ne sont pas un multiple entier de tels groupes de 3 octets, elles doivent être complétées avec un ou deux octets zéro. Pour indiquer le nombre d'octets de remplissage ajoutés, un ou deux caractères = sont ajoutés à la chaîne codée.

transform_width, qui est responsable de la conversion 8 bits binaire en entier 6 bits ne s'applique pas automatiquement ce remplissage, il a été fait par l'utilisateur. Un exemple 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; 
} 

Notez que j'ai ajouté les insert_linebreaks et remove_whitespace itérateurs, de sorte que la sortie de base64 est bien formaté et entrée base64 avec des sauts de ligne peut être décodé. Ce sont optionnels cependant.

Exécuter avec différentes chaînes d'entrée qui nécessitent un rembourrage différent:

$ ./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!!! 

Vous pouvez vérifier les chaînes de base64 avec ce online-encoder/decoder.

+2

Bravo pour l'ajout d'un codage complet/décode l'implémentation! Le manque de rembourrage m'a aussi surpris. – DanDan

+0

pouvez-vous expliquer pourquoi vous avez besoin de second% 3 dans (3-s.length()% 3)% 3 – NoSenseEtAl

+0

Nous avons besoin d'un résultat dans {0,1,2}. Sans le second% 3, nous obtenons un résultat dans {1,2,3}. Le dernier% 3 mappe le résultat 3 à 0 et laisse 1 et 2 seuls. Une autre possibilité serait quelque chose comme s.length()% 3? 3-s.length()% 3: 0 – PiQuer