Browse code
Add base32 encoder prototype
Ed Langley authored on 02/06/2017 18:00:49
Showing 1 changed files
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 |
+} |