1 | //======================================================================== |
2 | // |
3 | // gbase64.cc |
4 | // |
5 | // Implementation of a base64 encoder, because another one did not immediately |
6 | // avail itself. |
7 | // |
8 | // This file is licensed under the GPLv2 or later |
9 | // |
10 | // Copyright (C) 2018 Greg Knight <lyngvi@gmail.com> |
11 | // |
12 | //======================================================================== |
13 | |
14 | #include "gbase64.h" |
15 | #include <sstream> |
16 | |
17 | static void b64encodeTriplet(char output[4], unsigned char a, unsigned char b, unsigned char c) |
18 | { |
19 | static const char *base64table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ; |
20 | output[0] = base64table[((a >> 2) & 0x3f)]; // upper 6 of first byte |
21 | output[1] = base64table[((a << 4) & 0x30) | ((b >> 4) & 0x0f)]; // lower 2 of first byte, upper 4 of second byte |
22 | output[2] = base64table[((b << 2) & 0x3c) | ((c >> 6) & 0x03)]; // lower 4 of second byte, upper 2 of third byte |
23 | output[3] = base64table[((c)&0x3f)]; // lower 6 of third byte |
24 | } |
25 | |
26 | std::string gbase64Encode(const void *input, size_t len) |
27 | { |
28 | char quad[4]; |
29 | size_t pos = 0; |
30 | std::stringstream buf; |
31 | auto bytes = static_cast<const unsigned char *>(input); |
32 | for (; pos + 3 <= len; pos += 3) { |
33 | b64encodeTriplet(output: quad, a: bytes[0], b: bytes[1], c: bytes[2]); |
34 | buf.write(s: &quad[0], n: 4); |
35 | bytes += 3; |
36 | } |
37 | switch (len - pos) { |
38 | case 1: |
39 | b64encodeTriplet(output: quad, a: bytes[0], b: 0, c: 0); |
40 | quad[2] = quad[3] = '='; |
41 | buf.write(s: &quad[0], n: 4); |
42 | break; |
43 | case 2: |
44 | b64encodeTriplet(output: quad, a: bytes[0], b: bytes[1], c: 0); |
45 | quad[3] = '='; |
46 | buf.write(s: &quad[0], n: 4); |
47 | break; |
48 | } |
49 | return buf.str(); |
50 | } |
51 | |