rippled
Loading...
Searching...
No Matches
base64.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012-2018 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20//
21// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
22//
23// Distributed under the Boost Software License, Version 1.0. (See accompanying
24// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
25//
26
27/*
28 Portions from http://www.adp-gmbh.ch/cpp/common/base64.html
29 Copyright notice:
30
31 base64.cpp and base64.h
32
33 Copyright (C) 2004-2008 René Nyffenegger
34
35 This source code is provided 'as-is', without any express or implied
36 warranty. In no event will the author be held liable for any damages
37 arising from the use of this software.
38
39 Permission is granted to anyone to use this software for any purpose,
40 including commercial applications, and to alter it and redistribute it
41 freely, subject to the following restrictions:
42
43 1. The origin of this source code must not be misrepresented; you must not
44 claim that you wrote the original source code. If you use this source code
45 in a product, an acknowledgment in the product documentation would be
46 appreciated but is not required.
47
48 2. Altered source versions must be plainly marked as such, and must not be
49 misrepresented as being the original source code.
50
51 3. This notice may not be removed or altered from any source distribution.
52
53 René Nyffenegger rene.nyffenegger@adp-gmbh.ch
54
55*/
56
57#include <xrpl/basics/base64.h>
58
59#include <cctype>
60#include <utility>
61
62namespace ripple {
63
64namespace base64 {
65
66inline char const*
68{
69 static char constexpr tab[] = {
70 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"};
71 return &tab[0];
72}
73
74inline signed char const*
76{
77 static signed char constexpr tab[] = {
78 -1, -1, -1, -1, -1, -1, -1, -1,
79 -1, -1, -1, -1, -1, -1, -1, -1, // 0-15
80 -1, -1, -1, -1, -1, -1, -1, -1,
81 -1, -1, -1, -1, -1, -1, -1, -1, // 16-31
82 -1, -1, -1, -1, -1, -1, -1, -1,
83 -1, -1, -1, 62, -1, -1, -1, 63, // 32-47
84 52, 53, 54, 55, 56, 57, 58, 59,
85 60, 61, -1, -1, -1, -1, -1, -1, // 48-63
86 -1, 0, 1, 2, 3, 4, 5, 6,
87 7, 8, 9, 10, 11, 12, 13, 14, // 64-79
88 15, 16, 17, 18, 19, 20, 21, 22,
89 23, 24, 25, -1, -1, -1, -1, -1, // 80-95
90 -1, 26, 27, 28, 29, 30, 31, 32,
91 33, 34, 35, 36, 37, 38, 39, 40, // 96-111
92 41, 42, 43, 44, 45, 46, 47, 48,
93 49, 50, 51, -1, -1, -1, -1, -1, // 112-127
94 -1, -1, -1, -1, -1, -1, -1, -1,
95 -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
96 -1, -1, -1, -1, -1, -1, -1, -1,
97 -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
98 -1, -1, -1, -1, -1, -1, -1, -1,
99 -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
100 -1, -1, -1, -1, -1, -1, -1, -1,
101 -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
102 -1, -1, -1, -1, -1, -1, -1, -1,
103 -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
104 -1, -1, -1, -1, -1, -1, -1, -1,
105 -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
106 -1, -1, -1, -1, -1, -1, -1, -1,
107 -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
108 -1, -1, -1, -1, -1, -1, -1, -1,
109 -1, -1, -1, -1, -1, -1, -1, -1 // 240-255
110 };
111 return &tab[0];
112}
113
116{
117 return 4 * ((n + 2) / 3);
118}
119
122{
123 return ((n / 4) * 3) + 2;
124}
125
139encode(void* dest, void const* src, std::size_t len)
140{
141 char* out = static_cast<char*>(dest);
142 char const* in = static_cast<char const*>(src);
143 auto const tab = base64::get_alphabet();
144
145 for (auto n = len / 3; n--;)
146 {
147 *out++ = tab[(in[0] & 0xfc) >> 2];
148 *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
149 *out++ = tab[((in[2] & 0xc0) >> 6) + ((in[1] & 0x0f) << 2)];
150 *out++ = tab[in[2] & 0x3f];
151 in += 3;
152 }
153
154 switch (len % 3)
155 {
156 case 2:
157 *out++ = tab[(in[0] & 0xfc) >> 2];
158 *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
159 *out++ = tab[(in[1] & 0x0f) << 2];
160 *out++ = '=';
161 break;
162
163 case 1:
164 *out++ = tab[(in[0] & 0xfc) >> 2];
165 *out++ = tab[((in[0] & 0x03) << 4)];
166 *out++ = '=';
167 *out++ = '=';
168 break;
169
170 case 0:
171 break;
172 }
173
174 return out - static_cast<char*>(dest);
175}
176
189decode(void* dest, char const* src, std::size_t len)
190{
191 char* out = static_cast<char*>(dest);
192 auto in = reinterpret_cast<unsigned char const*>(src);
193 unsigned char c3[3]{}, c4[4]{};
194 int i = 0;
195 int j = 0;
196
197 auto const inverse = base64::get_inverse();
198
199 while (len-- && *in != '=')
200 {
201 auto const v = inverse[*in];
202 if (v == -1)
203 break;
204 ++in;
205 c4[i] = v;
206 if (++i == 4)
207 {
208 c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
209 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
210 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
211
212 for (i = 0; i < 3; i++)
213 *out++ = c3[i];
214 i = 0;
215 }
216 }
217
218 if (i)
219 {
220 c3[0] = (c4[0] << 2) + ((c4[1] & 0x30) >> 4);
221 c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
222 c3[2] = ((c4[2] & 0x3) << 6) + c4[3];
223
224 for (j = 0; j < i - 1; j++)
225 *out++ = c3[j];
226 }
227
228 return {
229 out - static_cast<char*>(dest),
230 in - reinterpret_cast<unsigned char const*>(src)};
231}
232
233} // namespace base64
234
237{
238 std::string dest;
239 dest.resize(base64::encoded_size(len));
240 dest.resize(base64::encode(&dest[0], data, len));
241 return dest;
242}
243
246{
247 std::string dest;
248 dest.resize(base64::decoded_size(data.size()));
249 auto const result = base64::decode(&dest[0], data.data(), data.size());
250 dest.resize(result.first);
251 return dest;
252}
253
254} // namespace ripple
std::pair< std::size_t, std::size_t > decode(void *dest, char const *src, std::size_t len)
Decode a padded base64 string into a series of octets.
Definition: base64.cpp:189
signed char const * get_inverse()
Definition: base64.cpp:75
char const * get_alphabet()
Definition: base64.cpp:67
std::size_t encode(void *dest, void const *src, std::size_t len)
Encode a series of octets as a padded, base64 string.
Definition: base64.cpp:139
std::size_t constexpr decoded_size(std::size_t n)
Returns max bytes needed to decode a base64 string.
Definition: base64.cpp:121
std::size_t constexpr encoded_size(std::size_t n)
Returns max chars needed to encode a base64 string.
Definition: base64.cpp:115
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
std::string base64_decode(std::string_view data)
Definition: base64.cpp:245
std::string base64_encode(std::uint8_t const *data, std::size_t len)
Definition: base64.cpp:236
T resize(T... args)