@@ -95,68 +95,95 @@ const uint8_t base64de[] = {
95
95
};
96
96
}
97
97
98
- size_t Encode (const void *in, size_t inlen, char *out , size_t outlen )
98
+ size_t DecodeLength (const char *base64_ptr , size_t base64_size )
99
99
{
100
- TBOX_ASSERT (in != nullptr );
101
- TBOX_ASSERT (out != nullptr );
100
+ if (base64_size == 0 || (base64_size & 0x3 ) != 0 )
101
+ return 0 ;
102
+
103
+ size_t len = base64_size / 4 * 3 ;
104
+ // ! 检查字串尾部的=符号
105
+ if (base64_ptr[base64_size - 1 ] == BASE64_PAD)
106
+ --len;
107
+ if (base64_ptr[base64_size - 2 ] == BASE64_PAD)
108
+ --len;
109
+ return len;
110
+ }
111
+
112
+ size_t DecodeLength (const char *base64_str)
113
+ {
114
+ return DecodeLength (base64_str, ::strlen (base64_str));
115
+ }
116
+
117
+ size_t DecodeLength (const std::string &base64_str)
118
+ {
119
+ return DecodeLength (base64_str.data (), base64_str.length ());
120
+ }
121
+
122
+ size_t Encode (const void *raw_data_ptr, size_t raw_data_len, char *base64_ptr, size_t base64_size)
123
+ {
124
+ TBOX_ASSERT (raw_data_ptr != nullptr );
125
+ TBOX_ASSERT (raw_data_len > 0 );
126
+ TBOX_ASSERT (base64_ptr != nullptr );
127
+ TBOX_ASSERT (base64_size > 0 );
102
128
103
- if (EncodeLength (inlen ) > outlen )
129
+ if (EncodeLength (raw_data_len ) > base64_size )
104
130
return 0 ;
105
131
106
132
int s = 0 ;
107
133
uint8_t l = 0 ;
108
134
size_t w_pos = 0 ;
109
- const uint8_t *in_bytes = static_cast <const uint8_t *>(in );
135
+ const uint8_t *in_bytes = static_cast <const uint8_t *>(raw_data_ptr );
110
136
111
- for (size_t r_pos = 0 ; r_pos < inlen ; r_pos++) {
137
+ for (size_t r_pos = 0 ; r_pos < raw_data_len ; r_pos++) {
112
138
uint8_t c = in_bytes[r_pos];
113
139
114
140
switch (s) {
115
141
case 0 :
116
142
s = 1 ;
117
- out [w_pos++] = base64en[(c >> 2 ) & 0x3F ];
143
+ base64_ptr [w_pos++] = base64en[(c >> 2 ) & 0x3F ];
118
144
break ;
119
145
case 1 :
120
146
s = 2 ;
121
- out [w_pos++] = base64en[((l & 0x3 ) << 4 ) | ((c >> 4 ) & 0xF )];
147
+ base64_ptr [w_pos++] = base64en[((l & 0x3 ) << 4 ) | ((c >> 4 ) & 0xF )];
122
148
break ;
123
149
case 2 :
124
150
s = 0 ;
125
- out [w_pos++] = base64en[((l & 0xF ) << 2 ) | ((c >> 6 ) & 0x3 )];
126
- out [w_pos++] = base64en[c & 0x3F ];
151
+ base64_ptr [w_pos++] = base64en[((l & 0xF ) << 2 ) | ((c >> 6 ) & 0x3 )];
152
+ base64_ptr [w_pos++] = base64en[c & 0x3F ];
127
153
break ;
128
154
}
129
155
l = c;
130
156
}
131
157
132
158
switch (s) {
133
159
case 1 :
134
- out [w_pos++] = base64en[(l & 0x3 ) << 4 ];
135
- out [w_pos++] = BASE64_PAD;
136
- out [w_pos++] = BASE64_PAD;
160
+ base64_ptr [w_pos++] = base64en[(l & 0x3 ) << 4 ];
161
+ base64_ptr [w_pos++] = BASE64_PAD;
162
+ base64_ptr [w_pos++] = BASE64_PAD;
137
163
break ;
138
164
case 2 :
139
- out [w_pos++] = base64en[(l & 0xF ) << 2 ];
140
- out [w_pos++] = BASE64_PAD;
165
+ base64_ptr [w_pos++] = base64en[(l & 0xF ) << 2 ];
166
+ base64_ptr [w_pos++] = BASE64_PAD;
141
167
break ;
142
168
}
143
169
144
170
return w_pos;
145
171
}
146
172
147
- std::string Encode (const void *in , size_t inlen )
173
+ std::string Encode (const void *raw_data_ptr , size_t raw_data_len )
148
174
{
149
- TBOX_ASSERT (in != nullptr );
175
+ TBOX_ASSERT (raw_data_ptr != nullptr );
176
+ TBOX_ASSERT (raw_data_len > 0 );
150
177
151
178
std::string base64_str;
152
- auto base64_len = EncodeLength (inlen );
179
+ auto base64_len = EncodeLength (raw_data_len );
153
180
base64_str.reserve (base64_len);
154
181
155
182
uint8_t l = 0 ;
156
183
uint8_t s = 0 ;
157
- const uint8_t *in_bytes = static_cast <const uint8_t *>(in );
184
+ const uint8_t *in_bytes = static_cast <const uint8_t *>(raw_data_ptr );
158
185
159
- for (size_t r_pos = 0 ; r_pos < inlen ; ++r_pos) {
186
+ for (size_t r_pos = 0 ; r_pos < raw_data_len ; ++r_pos) {
160
187
uint8_t c = in_bytes[r_pos];
161
188
162
189
switch (s) {
@@ -192,72 +219,104 @@ std::string Encode(const void *in, size_t inlen)
192
219
return base64_str;
193
220
}
194
221
195
- size_t Decode (const char *in, size_t inlen, void *out, size_t outlen)
222
+ std::string Encode (const std::vector<uint8_t > &raw_data)
223
+ {
224
+ return Encode (raw_data.data (), raw_data.size ());
225
+ }
226
+
227
+ size_t Decode (const char *base64_ptr, size_t base64_len, void *raw_data_ptr, size_t raw_data_size)
196
228
{
197
- TBOX_ASSERT (in != nullptr );
198
- TBOX_ASSERT (out != nullptr );
229
+ TBOX_ASSERT (base64_ptr != nullptr );
230
+ TBOX_ASSERT (raw_data_ptr != nullptr );
199
231
200
- if (inlen & 0x3 )
232
+ if (base64_len & 0x3 )
201
233
return 0 ;
202
234
203
- if (DecodeLength (in, inlen ) > outlen )
235
+ if (DecodeLength (base64_ptr, base64_len ) > raw_data_size )
204
236
return 0 ;
205
237
206
238
size_t w_pos = 0 ;
207
- uint8_t *out_bytes = static_cast <uint8_t *>(out );
239
+ uint8_t *out_bytes = static_cast <uint8_t *>(raw_data_ptr );
208
240
209
- for (size_t r_pos = 0 ; r_pos < inlen ; r_pos++) {
210
- char in_c = in [r_pos];
211
- if (in_c == BASE64_PAD)
241
+ for (size_t r_pos = 0 ; r_pos < base64_len ; r_pos++) {
242
+ char c = base64_ptr [r_pos];
243
+ if (c == BASE64_PAD)
212
244
break ;
213
245
214
- uint8_t c = base64de[int (in_c )];
215
- if (c == 255 )
246
+ uint8_t v = base64de[int (c )];
247
+ if (v == 255 )
216
248
return 0 ;
217
249
218
250
switch (r_pos & 0x3 ) {
219
251
case 0 :
220
- out_bytes[w_pos] = (c << 2 ) & 0xFF ;
252
+ out_bytes[w_pos] = v << 2 ;
221
253
break ;
222
254
case 1 :
223
- out_bytes[w_pos++] |= (c >> 4 ) & 0x3 ;
224
- out_bytes[w_pos] = (c & 0xF ) << 4 ;
255
+ out_bytes[w_pos++] |= v >> 4 ;
256
+ out_bytes[w_pos] = v << 4 ;
225
257
break ;
226
258
case 2 :
227
- out_bytes[w_pos++] |= (c >> 2 ) & 0xF ;
228
- out_bytes[w_pos] = (c & 0x3 ) << 6 ;
259
+ out_bytes[w_pos++] |= v >> 2 ;
260
+ out_bytes[w_pos] = v << 6 ;
229
261
break ;
230
262
case 3 :
231
- out_bytes[w_pos++] |= c ;
263
+ out_bytes[w_pos++] |= v ;
232
264
break ;
233
265
}
234
266
}
235
267
236
268
return w_pos;
237
269
}
238
270
239
- size_t DecodeLength (const char *encode_str, size_t encode_str_len )
271
+ size_t Decode (const char *base64_str, void *raw_data_ptr, size_t raw_data_size )
240
272
{
241
- if (encode_str_len == 0 || (encode_str_len & 0x3 ) != 0 )
242
- return 0 ;
243
-
244
- size_t len = encode_str_len / 4 * 3 ;
245
- // ! 检查字串尾部的=符号
246
- if (encode_str[encode_str_len - 1 ] == BASE64_PAD)
247
- --len;
248
- if (encode_str[encode_str_len - 2 ] == BASE64_PAD)
249
- --len;
250
- return len;
273
+ return Decode (base64_str, ::strlen (base64_str), raw_data_ptr, raw_data_size);
251
274
}
252
275
253
- size_t DecodeLength (const char *encode_str )
276
+ size_t Decode (const std::string &base64_str, std::vector< uint8_t > &raw_data )
254
277
{
255
- return DecodeLength (encode_str, ::strlen (encode_str));
256
- }
278
+ size_t out_len = DecodeLength (base64_str);
279
+ if (out_len == 0 )
280
+ return 0 ;
257
281
258
- size_t DecodeLength (const std::string &encode_str)
259
- {
260
- return DecodeLength (encode_str.data (), encode_str.length ());
282
+ raw_data.reserve (raw_data.size () + out_len);
283
+
284
+ uint8_t tmp = 0 ;
285
+ uint8_t s = 0 ;
286
+
287
+ for (char c : base64_str) {
288
+ if (c == BASE64_PAD)
289
+ break ;
290
+
291
+ uint8_t v = base64de[int (c)];
292
+ if (v == 255 )
293
+ return 0 ;
294
+
295
+ switch (s) {
296
+ case 0 :
297
+ tmp = v << 2 ;
298
+ break ;
299
+ case 1 :
300
+ tmp |= v >> 4 ;
301
+ raw_data.push_back (tmp);
302
+ tmp = v << 4 ;
303
+ break ;
304
+ case 2 :
305
+ tmp |= v >> 2 ;
306
+ raw_data.push_back (tmp);
307
+ tmp = v << 6 ;
308
+ break ;
309
+ case 3 :
310
+ tmp |= v;
311
+ raw_data.push_back (tmp);
312
+ break ;
313
+ }
314
+
315
+ ++s;
316
+ s &= 0x03 ;
317
+ }
318
+
319
+ return out_len;
261
320
}
262
321
263
322
}
0 commit comments