34 #ifndef __BIN2ASCII_H__ 35 #define __BIN2ASCII_H__ 40 inline std::string hex2bin(
const std::string &s)
43 throw std::runtime_error(
"Odd hex data size");
44 static const char lookup[] =
"" 45 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 46 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 47 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 48 "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x80\x80\x80\x80\x80\x80" 49 "\x80\x0a\x0b\x0c\x0d\x0e\x0f\x80\x80\x80\x80\x80\x80\x80\x80\x80" 50 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 51 "\x80\x0a\x0b\x0c\x0d\x0e\x0f\x80\x80\x80\x80\x80\x80\x80\x80\x80" 52 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 53 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 54 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 55 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 56 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 57 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 58 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 59 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 60 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 63 r.reserve(s.size() / 2);
64 for (
size_t i = 0; i < s.size(); i += 2) {
65 char hi = lookup[
static_cast<unsigned char>(s[i])];
66 char lo = lookup[
static_cast<unsigned char>(s[i+1])];
68 throw std::runtime_error(
"Invalid hex data: " + s.substr(i, 6));
69 r.push_back((hi << 4) | lo);
74 inline std::string bin2hex(
const std::string &s)
76 static const char lookup[] =
"0123456789abcdef";
78 r.reserve(s.size() * 2);
79 for (
size_t i = 0; i < s.size(); i++) {
80 unsigned char hi = s[i] >> 4;
81 unsigned char lo = s[i] & 0xf;
82 r.push_back(lookup[hi]);
83 r.push_back(lookup[lo]);
88 inline void b64_strip(std::string &s)
90 if (s.empty())
return;
91 while (s.back()==
'=') s.pop_back();
94 inline void b64_strip(std::string* s)
96 if (s->empty())
return;
97 while (s->back()==
'=') s->pop_back();
100 inline void b64_sanit(std::string &s)
102 size_t pad=3 - ((s.length() + 3) % 4);
103 if (pad>0) s.resize(s.length()+pad,
'=');
106 inline void b64_sanit(std::string* s)
108 size_t pad=3 - ((s->length() + 3) % 4);
109 if (pad>0) s->resize(s->length()+pad,
'=');
112 inline std::string b64_encode(
const std::string &s,
bool strip=
false)
114 typedef unsigned char u1;
115 static const char lookup[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
116 const u1 * data = (
const u1 *) s.c_str();
118 r.reserve(s.size() * 4 / 3 + 3);
119 for (
size_t i = 0; i < s.size(); i += 3) {
120 unsigned n = data[i] << 16;
121 if (i + 1 < s.size()) n |= data[i + 1] << 8;
122 if (i + 2 < s.size()) n |= data[i + 2];
124 u1 n0 = (u1)(n >> 18) & 0x3f;
125 u1 n1 = (u1)(n >> 12) & 0x3f;
126 u1 n2 = (u1)(n >> 6) & 0x3f;
127 u1 n3 = (u1)(n ) & 0x3f;
129 r.push_back(lookup[n0]);
130 r.push_back(lookup[n1]);
131 if (i + 1 < s.size()) r.push_back(lookup[n2]);
132 if (i + 2 < s.size()) r.push_back(lookup[n3]);
135 for (
size_t i = 0; i < (3 - s.size() % 3) % 3; i++)
141 inline std::string b64_encode_strip(
const std::string &s)
143 return b64_encode(s,
true);
146 inline std::string b64_decode(
const std::string &s)
148 typedef unsigned char u1;
149 static const char lookup[] =
"" 150 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 151 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 152 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x3e\x80\x80\x80\x3f" 153 "\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x80\x80\x80\x00\x80\x80" 154 "\x80\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e" 155 "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x80\x80\x80\x80\x80" 156 "\x80\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28" 157 "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x80\x80\x80\x80\x80" 158 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 159 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 160 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 161 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 162 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 163 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 164 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 165 "\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80" 168 if (!s.size())
return r;
170 throw std::runtime_error(
"Invalid base64 data size");
172 if (s[s.size() - 1] ==
'=') pad++;
173 if (s[s.size() - 2] ==
'=') pad++;
175 r.reserve(s.size() * 3 / 4 + 3);
176 for (
size_t i = 0; i < s.size(); i += 4) {
177 u1 n0 = lookup[(u1) s[i+0]];
178 u1 n1 = lookup[(u1) s[i+1]];
179 u1 n2 = lookup[(u1) s[i+2]];
180 u1 n3 = lookup[(u1) s[i+3]];
181 if (0x80 & (n0 | n1 | n2 | n3))
182 throw std::runtime_error(
"Invalid hex data: " + s.substr(i, 4));
183 unsigned n = (n0 << 18) | (n1 << 12) | (n2 << 6) | n3;
184 r.push_back((n >> 16) & 0xff);
185 if (s[i+2] !=
'=') r.push_back((n >> 8) & 0xff);
186 if (s[i+3] !=
'=') r.push_back((n ) & 0xff);
191 inline std::string b64_sanit_decode(
const std::string &s)
195 return b64_decode(t);
197 #endif//__BIN2ASCII_H__