1
+ #ifndef _MACARON_BASE64_H_
2
+ #define _MACARON_BASE64_H_
3
+
4
+ /* *
5
+ * The MIT License (MIT)
6
+ * Copyright (c) 2016 tomykaira
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining
9
+ * a copy of this software and associated documentation files (the
10
+ * "Software"), to deal in the Software without restriction, including
11
+ * without limitation the rights to use, copy, modify, merge, publish,
12
+ * distribute, sublicense, and/or sell copies of the Software, and to
13
+ * permit persons to whom the Software is furnished to do so, subject to
14
+ * the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be
17
+ * included in all copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include < string>
29
+
30
+ class Base64 {
31
+ public:
32
+
33
+ static std::string Encode (const std::string data) {
34
+ static constexpr char sEncodingTable [] = {
35
+ ' A' , ' B' , ' C' , ' D' , ' E' , ' F' , ' G' , ' H' ,
36
+ ' I' , ' J' , ' K' , ' L' , ' M' , ' N' , ' O' , ' P' ,
37
+ ' Q' , ' R' , ' S' , ' T' , ' U' , ' V' , ' W' , ' X' ,
38
+ ' Y' , ' Z' , ' a' , ' b' , ' c' , ' d' , ' e' , ' f' ,
39
+ ' g' , ' h' , ' i' , ' j' , ' k' , ' l' , ' m' , ' n' ,
40
+ ' o' , ' p' , ' q' , ' r' , ' s' , ' t' , ' u' , ' v' ,
41
+ ' w' , ' x' , ' y' , ' z' , ' 0' , ' 1' , ' 2' , ' 3' ,
42
+ ' 4' , ' 5' , ' 6' , ' 7' , ' 8' , ' 9' , ' +' , ' /'
43
+ };
44
+
45
+ size_t in_len = data.size ();
46
+ size_t out_len = 4 * ((in_len + 2 ) / 3 );
47
+ std::string ret (out_len, ' \0 ' );
48
+ size_t i;
49
+ char * p = const_cast <char *>(ret.c_str ());
50
+
51
+ for (i = 0 ; i < in_len - 2 ; i += 3 ) {
52
+ *p++ = sEncodingTable [(data[i] >> 2 ) & 0x3F ];
53
+ *p++ = sEncodingTable [((data[i] & 0x3 ) << 4 ) | ((int )(data[i + 1 ] & 0xF0 ) >> 4 )];
54
+ *p++ = sEncodingTable [((data[i + 1 ] & 0xF ) << 2 ) | ((int )(data[i + 2 ] & 0xC0 ) >> 6 )];
55
+ *p++ = sEncodingTable [data[i + 2 ] & 0x3F ];
56
+ }
57
+ if (i < in_len) {
58
+ *p++ = sEncodingTable [(data[i] >> 2 ) & 0x3F ];
59
+ if (i == (in_len - 1 )) {
60
+ *p++ = sEncodingTable [((data[i] & 0x3 ) << 4 )];
61
+ *p++ = ' =' ;
62
+ }
63
+ else {
64
+ *p++ = sEncodingTable [((data[i] & 0x3 ) << 4 ) | ((int )(data[i + 1 ] & 0xF0 ) >> 4 )];
65
+ *p++ = sEncodingTable [((data[i + 1 ] & 0xF ) << 2 )];
66
+ }
67
+ *p++ = ' =' ;
68
+ }
69
+
70
+ return ret;
71
+ }
72
+
73
+ static std::string Decode (const std::string& input, std::string& out) {
74
+ static constexpr unsigned char kDecodingTable [] = {
75
+ 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,
76
+ 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,
77
+ 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 62 , 64 , 64 , 64 , 63 ,
78
+ 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 64 , 64 , 64 , 64 , 64 , 64 ,
79
+ 64 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 ,
80
+ 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 64 , 64 , 64 , 64 , 64 ,
81
+ 64 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 ,
82
+ 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 64 , 64 , 64 , 64 , 64 ,
83
+ 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,
84
+ 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,
85
+ 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,
86
+ 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,
87
+ 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,
88
+ 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,
89
+ 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 ,
90
+ 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64 , 64
91
+ };
92
+
93
+ size_t in_len = input.size ();
94
+ if (in_len % 4 != 0 ) return " Input data size is not a multiple of 4" ;
95
+
96
+ size_t out_len = in_len / 4 * 3 ;
97
+ if (input[in_len - 1 ] == ' =' ) out_len--;
98
+ if (input[in_len - 2 ] == ' =' ) out_len--;
99
+
100
+ out.resize (out_len);
101
+
102
+ for (size_t i = 0 , j = 0 ; i < in_len;) {
103
+ uint32_t a = input[i] == ' =' ? 0 & i++ : kDecodingTable [static_cast <int >(input[i++])];
104
+ uint32_t b = input[i] == ' =' ? 0 & i++ : kDecodingTable [static_cast <int >(input[i++])];
105
+ uint32_t c = input[i] == ' =' ? 0 & i++ : kDecodingTable [static_cast <int >(input[i++])];
106
+ uint32_t d = input[i] == ' =' ? 0 & i++ : kDecodingTable [static_cast <int >(input[i++])];
107
+
108
+ uint32_t triple = (a << 3 * 6 ) + (b << 2 * 6 ) + (c << 1 * 6 ) + (d << 0 * 6 );
109
+
110
+ if (j < out_len) out[j++] = (triple >> 2 * 8 ) & 0xFF ;
111
+ if (j < out_len) out[j++] = (triple >> 1 * 8 ) & 0xFF ;
112
+ if (j < out_len) out[j++] = (triple >> 0 * 8 ) & 0xFF ;
113
+ }
114
+
115
+ return " " ;
116
+ }
117
+
118
+ };
119
+
120
+ #endif /* _MACARON_BASE64_H_ */
0 commit comments