git.fiddlerwoaroof.com
Browse code

Add base32 encoder prototype

Ed Langley authored on 02/06/2017 18:00:49
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,92 @@
1
+#include <iostream>
2
+#include <iomanip>
3
+#include <vector>
4
+
5
+std::string encodeBase32(const std::vector<uint8_t> data) {
6
+    std::vector<char> alphabet = {
7
+        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
8
+        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
9
+        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
10
+        'Y', 'Z', '2', '3', '4', '5', '6', '7'
11
+    };
12
+
13
+    uint8_t tmp = 0;
14
+    auto data_size = data.size();
15
+
16
+    std::string result;
17
+    auto begin = data.begin();
18
+    auto end = data.end();
19
+
20
+    auto extra_bytes = (data_size % 5);
21
+    auto padding_chars = 0;
22
+    switch (extra_bytes) {
23
+    case 1:
24
+        padding_chars = 6;
25
+        break;
26
+    case 2:
27
+        padding_chars = 4;
28
+        break;
29
+    case 3:
30
+        padding_chars = 3;
31
+        break;
32
+    case 4:
33
+        padding_chars = 1;
34
+        break;
35
+    }
36
+
37
+    auto leftover = (5 - extra_bytes) % 5;
38
+    for (auto cur = begin; cur+5 < (end + leftover + 1); cur+=5) {
39
+        std::vector<uint8_t> batch;
40
+        if (cur+5 < end) {
41
+             batch = std::vector<uint8_t> (cur, cur+5);
42
+        } else {
43
+             batch = std::vector<uint8_t> (cur, end);
44
+             for (int x = 0; x < leftover; x++) {
45
+                 batch.push_back(0);
46
+             }
47
+        }
48
+
49
+        std::bitset<40> everything;
50
+        everything |= (static_cast<uint64_t>(batch[0]) << 32);
51
+        everything |= (static_cast<uint64_t>(batch[1]) << 24);
52
+        everything |= (static_cast<uint64_t>(batch[2]) << 16);
53
+        everything |= (static_cast<uint64_t>(batch[3]) <<  8);
54
+        everything |=                        batch[4];
55
+
56
+        uint64_t mask = 31;
57
+        uint64_t offset = 35;
58
+        mask <<= offset;
59
+
60
+        int counter = 0;
61
+        while (offset <= 35) {
62
+            auto idx = everything;
63
+            idx &=  mask;
64
+            idx >>= offset;
65
+
66
+            mask >>= 5;
67
+            offset -= 5;
68
+
69
+            result.push_back(alphabet[idx.to_ullong()]);
70
+        }
71
+    }
72
+
73
+    if (padding_chars > 0) {
74
+        auto replace_end   = result.end();
75
+        auto replace_start = replace_end - padding_chars;
76
+        auto replace_count = replace_end - replace_start;
77
+
78
+        result.replace(replace_start, replace_end, replace_count, '=');
79
+    }
80
+
81
+    return result;
82
+}
83
+
84
+int main(int argc, char** argv) {
85
+    std::string data;
86
+    while (std::getline(std::cin,data)) {
87
+        std::vector<unsigned char> v(data.begin(), data.end());
88
+
89
+        std::string res = encodeBase32(v);
90
+        std::cout << "{\"ORIGINAL\": \"" << data << "\", \"BASE32\": \"" << res << "\"}" << std::endl;
91
+    }
92
+}