2 // Copyright (c) 2016-2019 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 Rene 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 Rene Nyffenegger rene.nyffenegger@adp-gmbh.ch
39 #ifndef BOOST_BEAST_DETAIL_BASE64_IPP
40 #define BOOST_BEAST_DETAIL_BASE64_IPP
42 #include <boost/beast/core/detail/base64.hpp>
43 #include <boost/beast/core/string.hpp>
57 static char constexpr tab[] = {
69 static signed char constexpr tab[] = {
70 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
71 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
72 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
73 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, // 48-63
74 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
75 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, // 80-95
76 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
77 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127
78 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
79 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
80 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
81 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
82 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
83 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
84 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
85 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // 240-255
90 /** Encode a series of octets as a padded, base64 string.
92 The resulting string will not be null terminated.
96 The memory pointed to by `out` points to valid memory
97 of at least `encoded_size(len)` bytes.
99 @return The number of characters written to `out`. This
100 will exclude any null termination.
103 encode(void* dest, void const* src, std::size_t len)
105 char* out = static_cast<char*>(dest);
106 char const* in = static_cast<char const*>(src);
107 auto const tab = base64::get_alphabet();
109 for(auto n = len / 3; n--;)
111 *out++ = tab[ (in[0] & 0xfc) >> 2];
112 *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
113 *out++ = tab[((in[2] & 0xc0) >> 6) + ((in[1] & 0x0f) << 2)];
114 *out++ = tab[ in[2] & 0x3f];
121 *out++ = tab[ (in[0] & 0xfc) >> 2];
122 *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
123 *out++ = tab[ (in[1] & 0x0f) << 2];
128 *out++ = tab[ (in[0] & 0xfc) >> 2];
129 *out++ = tab[((in[0] & 0x03) << 4)];
138 return out - static_cast<char*>(dest);
141 /** Decode a padded base64 string into a series of octets.
145 The memory pointed to by `out` points to valid memory
146 of at least `decoded_size(len)` bytes.
148 @return The number of octets written to `out`, and
149 the number of characters read from the input string,
152 std::pair<std::size_t, std::size_t>
153 decode(void* dest, char const* src, std::size_t len)
155 char* out = static_cast<char*>(dest);
156 auto in = reinterpret_cast<unsigned char const*>(src);
157 unsigned char c3[3], c4[4];
161 auto const inverse = base64::get_inverse();
163 while(len-- && *in != '=')
165 auto const v = inverse[*in];
172 c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
173 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
174 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
176 for(i = 0; i < 3; i++)
184 c3[0] = ( c4[0] << 2) + ((c4[1] & 0x30) >> 4);
185 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
186 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
188 for(j = 0; j < i - 1; j++)
192 return {out - static_cast<char*>(dest),
193 in - reinterpret_cast<unsigned char const*>(src)};