1 | #include "taichi/common/core.h" |
---|---|
2 | |
3 | namespace taichi { |
4 | /* |
5 | base64.cpp and base64.h |
6 | |
7 | Copyright (C) 2004-2008 René Nyffenegger |
8 | |
9 | This source code is provided 'as-is', without any express or implied |
10 | warranty. In no event will the author be held liable for any damages |
11 | arising from the use of this software. |
12 | |
13 | Permission is granted to anyone to use this software for any purpose, |
14 | including commercial applications, and to alter it and redistribute it |
15 | freely, subject to the following restrictions: |
16 | |
17 | 1. The origin of this source code must not be misrepresented; you must not |
18 | claim that you wrote the original source code. If you use this source code |
19 | in a product, an acknowledgment in the product documentation would be |
20 | appreciated but is not required. |
21 | |
22 | 2. Altered source versions must be plainly marked as such, and must not be |
23 | misrepresented as being the original source code. |
24 | |
25 | 3. This notice may not be removed or altered from any source distribution. |
26 | |
27 | René Nyffenegger [email protected] |
28 | */ |
29 | |
30 | static const std::string base64_chars = |
31 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
32 | "abcdefghijklmnopqrstuvwxyz" |
33 | "0123456789+/"; |
34 | |
35 | static inline bool is_base64(unsigned char c) { |
36 | return (isalnum(c) || (c == '+') || (c == '/')); |
37 | } |
38 | |
39 | inline std::string base64_encode(const std::string &bytes) { |
40 | auto bytes_to_encode = reinterpret_cast<unsigned char const *>(&bytes[0]); |
41 | unsigned int in_len = bytes.size(); |
42 | std::string ret; |
43 | int i = 0; |
44 | int j = 0; |
45 | unsigned char char_array_3[3]; |
46 | unsigned char char_array_4[4]; |
47 | |
48 | while (in_len--) { |
49 | char_array_3[i++] = *(bytes_to_encode++); |
50 | if (i == 3) { |
51 | char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; |
52 | char_array_4[1] = |
53 | ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); |
54 | char_array_4[2] = |
55 | ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); |
56 | char_array_4[3] = char_array_3[2] & 0x3f; |
57 | |
58 | for (i = 0; (i < 4); i++) |
59 | ret += base64_chars[char_array_4[i]]; |
60 | i = 0; |
61 | } |
62 | } |
63 | |
64 | if (i) { |
65 | for (j = i; j < 3; j++) |
66 | char_array_3[j] = '\0'; |
67 | |
68 | char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; |
69 | char_array_4[1] = |
70 | ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); |
71 | char_array_4[2] = |
72 | ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); |
73 | char_array_4[3] = char_array_3[2] & 0x3f; |
74 | |
75 | for (j = 0; (j < i + 1); j++) |
76 | ret += base64_chars[char_array_4[j]]; |
77 | |
78 | while ((i++ < 3)) |
79 | ret += '='; |
80 | } |
81 | |
82 | return ret; |
83 | } |
84 | |
85 | inline std::string base64_decode(std::string const &encoded_string) { |
86 | int in_len = encoded_string.size(); |
87 | int i = 0; |
88 | int j = 0; |
89 | int in_ = 0; |
90 | unsigned char char_array_4[4], char_array_3[3]; |
91 | std::string ret; |
92 | |
93 | while (in_len-- && (encoded_string[in_] != '=') && |
94 | is_base64(encoded_string[in_])) { |
95 | char_array_4[i++] = encoded_string[in_]; |
96 | in_++; |
97 | if (i == 4) { |
98 | for (i = 0; i < 4; i++) |
99 | char_array_4[i] = base64_chars.find(char_array_4[i]); |
100 | |
101 | char_array_3[0] = |
102 | (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); |
103 | char_array_3[1] = |
104 | ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); |
105 | char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; |
106 | |
107 | for (i = 0; (i < 3); i++) |
108 | ret += char_array_3[i]; |
109 | i = 0; |
110 | } |
111 | } |
112 | |
113 | if (i) { |
114 | for (j = i; j < 4; j++) |
115 | char_array_4[j] = 0; |
116 | |
117 | for (j = 0; j < 4; j++) |
118 | char_array_4[j] = base64_chars.find(char_array_4[j]); |
119 | |
120 | char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); |
121 | char_array_3[1] = |
122 | ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); |
123 | char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; |
124 | |
125 | for (j = 0; (j < i - 1); j++) |
126 | ret += char_array_3[j]; |
127 | } |
128 | |
129 | return ret; |
130 | } |
131 | |
132 | } // namespace taichi |
133 |