Base64-Codierung mit Boost-Throw-Ausnahme

Base64-Codierung mit Boost-Throw-Ausnahme


Beim Versuch, den Base64-Encoder zu verwenden, habe ich ein Beispiel gefunden, aber ich habe eine Ausnahme bekommen


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

und ich habe

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

Ich verstehe



Ich habe diese Problemumgehung gefunden, aber ich erhalte das gleiche Ergebnis


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

Ich verwende MSVS2008 und Boost 1.38


Antworten:


Leider die Kombination der beiden iterator_adaptors binary_from_base64 und transform_width ist kein vollständiger base64-Encoder/Decoder. Base64 stellt Gruppen von 24 Bit (3 Byte) als 4 Zeichen dar, die jeweils 6 Bit kodieren. Wenn die Eingangsdaten kein ganzzahliges Vielfaches solcher 3-Byte-Gruppen sind, müssen sie mit einem oder zwei Null-Bytes aufgefüllt werden. Um anzugeben, wie viele Füllbytes hinzugefügt wurden, ein oder zwei = Zeichen werden an die codierte Zeichenfolge angehängt.


transform_width , das für die Konvertierung von 8-Bit-Binärdaten in 6-Bit-Ganzzahlen verantwortlich ist, wendet dieses Auffüllen nicht automatisch an, sondern muss vom Benutzer vorgenommen werden. Ein einfaches Beispiel:


#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;
}

Beachten Sie, dass ich den insert_linebreaks hinzugefügt habe und remove_whitespace Iteratoren, damit die base64-Ausgabe schön formatiert ist und base64-Eingaben mit Zeilenumbrüchen dekodiert werden können. Diese sind jedoch optional.


Mit unterschiedlichen Eingabezeichenfolgen ausführen, die unterschiedliche Auffüllungen erfordern:


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

Sie können die base64-Strings mit diesem Online-Encoder/Decoder überprüfen.


Einige Code-Antworten


typedef  transform_width<
binary_from_base64<std::string::const_iterator>, 8, 6 >
it_binary_t
std::string b64E(it_binary_t(Encrip.begin()), it_binary_t(Encrip.end()));
 string dec(
it_binary_t(Encrip.begin()),
it_binary_t(Encrip.begin() + Encrip.length() - 1)
);
#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;
}
$ ./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!!!