How do I encode a string to base64 using only boost?

前端 未结 9 1009
南方客
南方客 2020-12-04 10:53

I\'m trying to quickly encode a simple ASCII string to base64 (Basic HTTP Authentication using boost::asio) and not paste in any new code code or use any libraries beyond bo

相关标签:
9条回答
  • 2020-12-04 11:37

    You could use beast's implementation.

    For boost version 1.71, the functions are:

    boost::beast::detail::base64::encode()
    boost::beast::detail::base64::encoded_size()
    boost::beast::detail::base64::decode()
    boost::beast::detail::base64::decoded_size()
    

    From #include <boost/beast/core/detail/base64.hpp>

    For older versions back to beast's inclusion in 1.66, the functions are:

    boost::beast::detail::base64_encode()
    boost::beast::detail::base64_decode()
    

    From #include <boost/beast/core/detail/base64.hpp>

    0 讨论(0)
  • 2020-12-04 11:37

    For anyone coming here from Google, here's my base64 encode/decode functions based off boost. It handles padding correctly as per DanDan's comment above. The decode functions stops when it encounters an illegal character, and returns a pointer to that character, which is great if you're parsing base64 in json or xml.

    ///
    /// Convert up to len bytes of binary data in src to base64 and store it in dest
    ///
    /// \param dest Destination buffer to hold the base64 data.
    /// \param src Source binary data.
    /// \param len The number of bytes of src to convert.
    ///
    /// \return The number of characters written to dest.
    /// \remarks Does not store a terminating null in dest.
    ///
    uint base64_encode(char* dest, const char* src, uint len)
    {
        char tail[3] = {0,0,0};
        typedef base64_from_binary<transform_width<const char *, 6, 8> > base64_enc;
    
        uint one_third_len = len/3;
        uint len_rounded_down = one_third_len*3;
        uint j = len_rounded_down + one_third_len;
    
        std::copy(base64_enc(src), base64_enc(src + len_rounded_down), dest);
    
        if (len_rounded_down != len)
        {
            uint i=0;
            for(; i < len - len_rounded_down; ++i)
            {
                tail[i] = src[len_rounded_down+i];
            }
    
            std::copy(base64_enc(tail), base64_enc(tail + 3), dest + j);
    
            for(i=len + one_third_len + 1; i < j+4; ++i)
            {
                dest[i] = '=';
            }
    
            return i;
        }
    
        return j;
    }
    
    ///
    /// Convert null-terminated string src from base64 to binary and store it in dest.
    ///
    /// \param dest Destination buffer
    /// \param src Source base64 string
    /// \param len Pointer to unsigned int representing size of dest buffer. After function returns this is set to the number of character written to dest.
    ///
    /// \return Pointer to first character in source that could not be converted (the terminating null on success)
    ///
    const char* base64_decode(char* dest, const char* src, uint* len)
    {
        uint output_len = *len;
    
        typedef transform_width<binary_from_base64<const char*>, 8, 6> base64_dec;
    
        uint i=0;
        try
        {
            base64_dec src_it(src);
            for(; i < output_len; ++i)
            {
                *dest++ = *src_it;
                ++src_it;
            }
        }
        catch(dataflow_exception&)
        {
        }
    
        *len = i;
        return src + (i+2)/3*4; // bytes in = bytes out / 3 rounded up * 4
    }
    
    0 讨论(0)
  • 2020-12-04 11:43

    I modified the Answer 8 because it's not functional on my platform.

    const std::string base64_padding[] = {"", "==","="};
    std::string *m_ArchiveData;
    
    /// \brief  To Base64 string
    bool Base64Encode(string* output) 
    {  
        try
        {
            UInt32 iPadding_Mask = 0;
            typedef boost::archive::iterators::base64_from_binary
                <boost::archive::iterators::transform_width<const char *, 6, 8> > Base64EncodeIterator;  
            UInt32 len = m_ArchiveData->size();
            std::stringstream os;
    
            std::copy(Base64EncodeIterator(m_ArchiveData->c_str()), 
                Base64EncodeIterator(m_ArchiveData->c_str()+len), 
                std::ostream_iterator<char>(os));
    
            iPadding_Mask = m_ArchiveData->size() % 3;
            os << base64_padding[iPadding_Pask];
    
            *output = os.str();
            return output->empty() == false;  
        }
        catch (...)
        {
            PLOG_ERROR_DEV("unknown error happens");
            return false;
        }
    }  
    
    /// \brief  From Base64 string
    bool mcsf_data_header_byte_stream_archive::Base64Decode(const std::string *input) 
    {  
        try
        {
            std::stringstream os;
            bool bPaded = false;
            typedef boost::archive::iterators::transform_width<boost::archive::iterators::
                binary_from_base64<const char *>, 8, 6> Base64DecodeIterator;  
    
            UInt32 iLength = input->length();
            // Remove the padding characters, cf. https://svn.boost.org/trac/boost/ticket/5629
            if (iLength && (*input)[iLength-1] == '=') {
                bPaded = true;
                --iLength;
                if (iLength && (*input)[iLength - 1] == '=') 
                {
                    --iLength;
                }
            }
            if (iLength == 0)
            {
                return false;
            }
    
            if(bPaded)
            {
                iLength --;
            }
    
            copy(Base64DecodeIterator(input->c_str()) ,
                Base64DecodeIterator(input->c_str()+iLength), 
                ostream_iterator<char>(os)); 
    
            *m_ArchiveData = os.str();
            return m_ArchiveData->empty() == false;
        }
        catch (...)
        {
            PLOG_ERROR_DEV("unknown error happens");
            return false;
        }
    }  
    
    0 讨论(0)
提交回复
热议问题