2012-05-09 9 views
7

I próbuje użyć doładowania base64 enkoder, znalazłem przykład, ale mam i wyjątekBase64 zakodować rzut użyciu doładowania wyjątek

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

użyłem

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

łapię

Nieobsługiwany wyjątek przy 0x75b1b9bc w pliku agentid_coder.exe: Microsoft C++ wyjątek: boost :: archiwum :: iteratory :: dataflow_exception w pamięci lokalizacji 0x0046ed94 ..

znalazłem tego obejścia, ale pojawia się ten sam wynik

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

używam MSVS2008 i zwiększenia 1,38

+0

Funkcje kodowania Base64 przy użyciu biblioteki Boost C++: http://stackoverflow.com/questions/34680998/attempt-to-decode-a-value-not-in-base64-char-set – ap6491

Odpowiedz

28

Niestety kombinacja dwóch iterator_adaptorsbinary_from_base64 i transform_width nie jest kompletnym koderem/dekoderem base64. Base64 reprezentuje grupy 24 bitów (3 bajty) jako 4 znaki, z których każda koduje 6 bitów. Jeśli dane wejściowe nie są wielokrotnością całkowitą takich 3-bajtowych grup, muszą być wypełnione jednym lub dwoma zerowymi bajtami. Aby wskazać, ile bajtów dopełnienia zostało dodanych, jeden lub dwa znaki = są dołączane do zakodowanego ciągu.

transform_width, która jest odpowiedzialna za 8bit konwersji binarnej na 6bitową nie stosuje tego wypełnienia automatycznie, musi to zrobić użytkownik. Prosty przykład:

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

Zauważ, że dodałem insert_linebreaks i remove_whitespace iteratory, tak że wyjście base64 jest ładnie sformatowany i wejście base64 z przerwami liniowych mogą być dekodowane. Są one jednak opcjonalne.

Run z różnych ciągów wejściowych, które wymagają innego 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!!! 

Można sprawdzić ciągów base64 z tym online-encoder/decoder.

+2

Dobra robota do dodania pełnego kodowania/implementacja dekodowania! Brak wyściółki również mnie zaskoczył. – DanDan

+0

czy możesz wyjaśnić, dlaczego potrzebujesz drugiej% 3 (3-s.length()% 3)% 3 – NoSenseEtAl

+0

Potrzebujemy wyniku {0,1,2}. Bez drugiego% 3 otrzymamy wynik w {1,2,3}. Ostatni% 3 odwzorowuje wynik od 3 do 0 i pozostawia tylko 1 i 2. Inną możliwością może być coś takiego jak s.length()% 3? 3-s.length()% 3: 0 – PiQuer