AlteriomPainlessMesh v2.1.1
Easy ESP32/ESP8266 mesh networking with Alteriom IoT extensions
Loading...
Searching...
No Matches
base64.hpp
Go to the documentation of this file.
1#ifndef _PAINLESS_MESH_BASE64_HPP_
2#define _PAINLESS_MESH_BASE64_HPP_
3
4#include <string>
5
7
8namespace painlessmesh {
9namespace base64 {
10
11static inline bool is_base64(unsigned char c) {
12 return (isalnum(c) || (c == '+') || (c == '/'));
13}
14
15static const TSTRING chars =
16 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
17 "abcdefghijklmnopqrstuvwxyz"
18 "0123456789+/";
19
20inline TSTRING encode(unsigned char const* bytes_to_encode,
21 unsigned int in_len) {
22 TSTRING ret;
23 int i = 0;
24 int j = 0;
25 unsigned char char_array_3[3];
26 unsigned char char_array_4[4];
27
28 while (in_len--) {
29 char_array_3[i++] = *(bytes_to_encode++);
30 if (i == 3) {
31 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
32 char_array_4[1] =
33 ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
34 char_array_4[2] =
35 ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
36 char_array_4[3] = char_array_3[2] & 0x3f;
37
38 for (i = 0; (i < 4); i++) ret += chars[char_array_4[i]];
39 i = 0;
40 }
41 }
42
43 if (i) {
44 for (j = i; j < 3; j++) char_array_3[j] = '\0';
45
46 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
47 char_array_4[1] =
48 ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
49 char_array_4[2] =
50 ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
51 char_array_4[3] = char_array_3[2] & 0x3f;
52 for (j = 0; (j < i + 1); j++) ret += chars[char_array_4[j]];
53 while ((i++ < 3)) ret += '=';
54 }
55
56 return ret;
57}
58
59inline TSTRING encode(const TSTRING& str64) {
60 return encode((unsigned char*)str64.c_str(), str64.length());
61}
62
63static const int B64index[256] = {
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66 0, 0, 0, 0, 0, 0, 0, 62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57,
67 58, 59, 60, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,
68 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
69 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
70 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
71
72inline const TSTRING decode(const void* data, const size_t& len) {
73 if (len == 0) return "";
74
75 unsigned char* p = (unsigned char*)data;
76 size_t j = 0, pad1 = len % 4 || p[len - 1] == '=',
77 pad2 = pad1 && (len % 4 > 2 || p[len - 2] != '=');
78 const size_t last = (len - pad1) / 4 << 2;
79#ifdef PAINLESSMESH_ENABLE_STD_STRING
80 TSTRING result(last / 4 * 3 + pad1 + pad2, '\0');
81#else
82 TSTRING result;
83 result.reserve(last / 4 * 3 + pad1 + pad2);
84 for (size_t i = 0; i < last / 4 * 3 + pad1 + pad2; ++i) result.concat('\0');
85#endif
86 unsigned char* str = (unsigned char*)&result[0];
87
88 for (size_t i = 0; i < last; i += 4) {
89 int n = B64index[p[i]] << 18 | B64index[p[i + 1]] << 12 |
90 B64index[p[i + 2]] << 6 | B64index[p[i + 3]];
91 str[j++] = n >> 16;
92 str[j++] = n >> 8 & 0xFF;
93 str[j++] = n & 0xFF;
94 }
95 if (pad1) {
96 int n = B64index[p[last]] << 18 | B64index[p[last + 1]] << 12;
97 str[j++] = n >> 16;
98 if (pad2) {
99 n |= B64index[p[last + 2]] << 6;
100 str[j++] = n >> 8 & 0xFF;
101 }
102 }
103 return result;
104}
105
106inline TSTRING decode(const TSTRING& str64) {
107 return decode(str64.c_str(), str64.length());
108}
109} // namespace base64
110} // namespace painlessmesh
111#endif
String TSTRING
Definition configuration.hpp:132
TSTRING encode(unsigned char const *bytes_to_encode, unsigned int in_len)
Definition base64.hpp:20
const TSTRING decode(const void *data, const size_t &len)
Definition base64.hpp:72
Definition wifi.hpp:34