2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 // Official repository: https://github.com/boostorg/beast
11 Portions from http://www.adp-gmbh.ch/cpp/common/base64.html
14 base64.cpp and base64.h
16 Copyright (C) 2004-2008 René Nyffenegger
18 This source code is provided 'as-is', without any express or implied
19 warranty. In no event will the author be held liable for any damages
20 arising from the use of this software.
22 Permission is granted to anyone to use this software for any purpose,
23 including commercial applications, and to alter it and redistribute it
24 freely, subject to the following restrictions:
26 1. The origin of this source code must not be misrepresented; you must not
27 claim that you wrote the original source code. If you use this source code
28 in a product, an acknowledgment in the product documentation would be
29 appreciated but is not required.
31 2. Altered source versions must be plainly marked as such, and must not be
32 misrepresented as being the original source code.
34 3. This notice may not be removed or altered from any source distribution.
36 René Nyffenegger rene.nyffenegger@adp-gmbh.ch
40 #ifndef BOOST_BEAST_DETAIL_BASE64_HPP
41 #define BOOST_BEAST_DETAIL_BASE64_HPP
57 static char constexpr tab[] = {
58 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
67 static signed char constexpr tab[] = {
68 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
69 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
70 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
71 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48-63
72 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
73 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80-95
74 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
75 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127
76 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
77 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
78 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
79 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
80 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
81 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
82 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
83 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255
89 /// Returns max chars needed to encode a base64 string
92 encoded_size(std::size_t n)
94 return 4 * ((n + 2) / 3);
97 /// Returns max bytes needed to decode a base64 string
100 decoded_size(std::size_t n)
102 return n / 4 * 3; // requires n&3==0, smaller
106 /** Encode a series of octets as a padded, base64 string.
108 The resulting string will not be null terminated.
112 The memory pointed to by `out` points to valid memory
113 of at least `encoded_size(len)` bytes.
115 @return The number of characters written to `out`. This
116 will exclude any null termination.
118 template<class = void>
120 encode(void* dest, void const* src, std::size_t len)
122 char* out = static_cast<char*>(dest);
123 char const* in = static_cast<char const*>(src);
124 auto const tab = base64::get_alphabet();
126 for(auto n = len / 3; n--;)
128 *out++ = tab[ (in[0] & 0xfc) >> 2];
129 *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
130 *out++ = tab[((in[2] & 0xc0) >> 6) + ((in[1] & 0x0f) << 2)];
131 *out++ = tab[ in[2] & 0x3f];
138 *out++ = tab[ (in[0] & 0xfc) >> 2];
139 *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
140 *out++ = tab[ (in[1] & 0x0f) << 2];
145 *out++ = tab[ (in[0] & 0xfc) >> 2];
146 *out++ = tab[((in[0] & 0x03) << 4)];
155 return out - static_cast<char*>(dest);
158 /** Decode a padded base64 string into a series of octets.
162 The memory pointed to by `out` points to valid memory
163 of at least `decoded_size(len)` bytes.
165 @return The number of octets written to `out`, and
166 the number of characters read from the input string,
169 template<class = void>
170 std::pair<std::size_t, std::size_t>
171 decode(void* dest, char const* src, std::size_t len)
173 char* out = static_cast<char*>(dest);
174 auto in = reinterpret_cast<unsigned char const*>(src);
175 unsigned char c3[3], c4[4];
179 auto const inverse = base64::get_inverse();
181 while(len-- && *in != '=')
183 auto const v = inverse[*in];
190 c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
191 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
192 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
194 for(i = 0; i < 3; i++)
202 c3[0] = ( c4[0] << 2) + ((c4[1] & 0x30) >> 4);
203 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
204 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
206 for(j = 0; j < i - 1; j++)
210 return {out - static_cast<char*>(dest),
211 in - reinterpret_cast<unsigned char const*>(src)};
216 template<class = void>
218 base64_encode (std::uint8_t const* data,
222 dest.resize(base64::encoded_size(len));
223 dest.resize(base64::encode(&dest[0], data, len));
229 base64_encode(std::string const& s)
231 return base64_encode (reinterpret_cast <
232 std::uint8_t const*> (s.data()), s.size());
235 template<class = void>
237 base64_decode(std::string const& data)
240 dest.resize(base64::decoded_size(data.size()));
241 auto const result = base64::decode(
242 &dest[0], data.data(), data.size());
243 dest.resize(result.first);