ゴミ箱
base64.hpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3 //
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)
6 //
7 // Official repository: https://github.com/boostorg/beast
8 //
9 
10 /*
11  Portions from http://www.adp-gmbh.ch/cpp/common/base64.html
12  Copyright notice:
13 
14  base64.cpp and base64.h
15 
16  Copyright (C) 2004-2008 René Nyffenegger
17 
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.
21 
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:
25 
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.
30 
31  2. Altered source versions must be plainly marked as such, and must not be
32  misrepresented as being the original source code.
33 
34  3. This notice may not be removed or altered from any source distribution.
35 
36  René Nyffenegger rene.nyffenegger@adp-gmbh.ch
37 
38 */
39 
40 #ifndef BOOST_BEAST_DETAIL_BASE64_HPP
41 #define BOOST_BEAST_DETAIL_BASE64_HPP
42 
43 #include <cctype>
44 #include <string>
45 #include <utility>
46 
47 namespace boost {
48 namespace beast {
49 namespace detail {
50 
51 namespace base64 {
52 
53 inline
54 char const*
56 {
57  static char constexpr tab[] = {
58  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
59  };
60  return &tab[0];
61 }
62 
63 inline
64 signed char const*
66 {
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
84  };
85  return &tab[0];
86 }
87 
88 
90 inline
91 std::size_t constexpr
92 encoded_size(std::size_t n)
93 {
94  return 4 * ((n + 2) / 3);
95 }
96 
98 inline
99 std::size_t constexpr
100 decoded_size(std::size_t n)
101 {
102  return n / 4 * 3; // requires n&3==0, smaller
103  //return 3 * n / 4;
104 }
105 
118 template<class = void>
119 std::size_t
120 encode(void* dest, void const* src, std::size_t len)
121 {
122  char* out = static_cast<char*>(dest);
123  char const* in = static_cast<char const*>(src);
124  auto const tab = base64::get_alphabet();
125 
126  for(auto n = len / 3; n--;)
127  {
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];
132  in += 3;
133  }
134 
135  switch(len % 3)
136  {
137  case 2:
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];
141  *out++ = '=';
142  break;
143 
144  case 1:
145  *out++ = tab[ (in[0] & 0xfc) >> 2];
146  *out++ = tab[((in[0] & 0x03) << 4)];
147  *out++ = '=';
148  *out++ = '=';
149  break;
150 
151  case 0:
152  break;
153  }
154 
155  return out - static_cast<char*>(dest);
156 }
157 
169 template<class = void>
170 std::pair<std::size_t, std::size_t>
171 decode(void* dest, char const* src, std::size_t len)
172 {
173  char* out = static_cast<char*>(dest);
174  auto in = reinterpret_cast<unsigned char const*>(src);
175  unsigned char c3[3], c4[4];
176  int i = 0;
177  int j = 0;
178 
179  auto const inverse = base64::get_inverse();
180 
181  while(len-- && *in != '=')
182  {
183  auto const v = inverse[*in];
184  if(v == -1)
185  break;
186  ++in;
187  c4[i] = v;
188  if(++i == 4)
189  {
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];
193 
194  for(i = 0; i < 3; i++)
195  *out++ = c3[i];
196  i = 0;
197  }
198  }
199 
200  if(i)
201  {
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];
205 
206  for(j = 0; j < i - 1; j++)
207  *out++ = c3[j];
208  }
209 
210  return {out - static_cast<char*>(dest),
211  in - reinterpret_cast<unsigned char const*>(src)};
212 }
213 
214 } // base64
215 
216 template<class = void>
217 std::string
218 base64_encode (std::uint8_t const* data,
219  std::size_t len)
220 {
221  std::string dest;
222  dest.resize(base64::encoded_size(len));
223  dest.resize(base64::encode(&dest[0], data, len));
224  return dest;
225 }
226 
227 inline
228 std::string
229 base64_encode(std::string const& s)
230 {
231  return base64_encode (reinterpret_cast <
232  std::uint8_t const*> (s.data()), s.size());
233 }
234 
235 template<class = void>
236 std::string
237 base64_decode(std::string const& data)
238 {
239  std::string dest;
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);
244  return dest;
245 }
246 
247 } // detail
248 } // beast
249 } // boost
250 
251 #endif
std::pair< std::size_t, std::size_t > decode(void *dest, char const *src, std::size_t len)
Definition: base64.hpp:171
Definition: async_result.hpp:20
std::string base64_decode(std::string const &data)
Definition: base64.hpp:237
std::string base64_encode(std::uint8_t const *data, std::size_t len)
Definition: base64.hpp:218
char const * get_alphabet()
Definition: base64.hpp:55
signed char const * get_inverse()
Definition: base64.hpp:65
std::size_t constexpr encoded_size(std::size_t n)
Returns max chars needed to encode a base64 string.
Definition: base64.hpp:92
std::size_t encode(void *dest, void const *src, std::size_t len)
Definition: base64.hpp:120
std::size_t constexpr decoded_size(std::size_t n)
Returns max bytes needed to decode a base64 string.
Definition: base64.hpp:100