Base64 encode using boost throw exception

前端 未结 1 1533
误落风尘
误落风尘 2020-12-13 22:36

I trying to use boost base64 encoder, I found an example but I got and exception

typedef 
transform_width< binary_from_base64

        
相关标签:
1条回答
  • 2020-12-13 22:57

    Unfortunately the combination of the two iterator_adaptors binary_from_base64 and transform_width is not a complete base64 encoder/decoder. Base64 represents groups of 24 bits (3 bytes) as 4 characters, each of which encodes 6 bits. If the input data is not an integer multiple of such 3 byte groups it has to be padded with one or two zero bytes. To indicate how many padding bytes were added, one or two = characters are appended to the encoded string.

    transform_width, which is responsible for the 8bit binary to 6bit integer conversion does not apply this padding automatically, it has do be done by the user. A simple example:

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

    Note that I added the insert_linebreaks and remove_whitespace iterators, so that the base64 output is nicely formatted and base64 input with line breaks can be decoded. These are optional though.

    Run with different input strings which require different 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!!!
    

    You can check the base64 strings with this online-encoder/decoder.

    0 讨论(0)
提交回复
热议问题